package com.uzai.console.service.xxljob.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.taobao.api.DefaultTaobaoClient;
import com.taobao.api.TaobaoClient;
import com.uzai.common.dto.device.DeviceInfoMobileWeChatCacheDto;
import com.uzai.common.dto.device.DeviceInfoMobileWxWorkCacheDto;
import com.uzai.common.dto.device.DeviceInfoPcWeChatCacheDto;
import com.uzai.common.dto.device.DeviceInfoWxWorkCacheDto;
import com.uzai.common.enums.*;
import com.uzai.common.enums.mini.MiniOrderStatus;
import com.uzai.common.exception.BusinessException;
import com.uzai.common.msg.MsgDto;
import com.uzai.common.protoc.SendSmsReqProtoc;
import com.uzai.common.result.ResponseCode;
import com.uzai.common.utils.DateFormatUtil;
import com.uzai.common.utils.EsIndexName;
import com.uzai.console.common.UzaiRespVo;
import com.uzai.console.common.utils.DateUtil;
import com.uzai.console.common.utils.Tools;
import com.uzai.console.config.UzaiConsoleSysConfig;
import com.uzai.console.constant.Const;
import com.uzai.console.constant.ES.ElasticsearchUtilGroupMsg;
import com.uzai.console.dto.contract.ContractSignQuery;
import com.uzai.console.dto.device.deviceauth.DeviceAuthQuery;
import com.uzai.console.dto.dingding.DingWarningGroupQuery;
import com.uzai.console.dto.dy.dytoken.DyTokenQuery;
import com.uzai.console.dto.fd.fdautoconfig.FdAutoConfigQuery;
import com.uzai.console.dto.fd.fdgoodspara.FdGoodsParaQuery;
import com.uzai.console.dto.fd.fdsendjob.FdSendJobQuery;
import com.uzai.console.dto.fd.fdtemplate.FdTemplateQuery;
import com.uzai.console.dto.feign.alarm.AlarmMsgFeignDto;
import com.uzai.console.dto.feign.config.ClearDeviceCacheDto;
import com.uzai.console.dto.md.mdactivity.MdActivityQuery;
import com.uzai.console.dto.md.mdexchange.MdExchangeQuery;
import com.uzai.console.dto.merbaseconfig.MerBaseConfigQuery;
import com.uzai.console.dto.mini.minicomponentauth.MiniComponentAuthQuery;
import com.uzai.console.dto.mini.miniorder.MiniOrderQuery;
import com.uzai.console.dto.orderpull.OrderPullQuery;
import com.uzai.console.dto.pdd.pddtoken.PddTokenQuery;
import com.uzai.console.dto.pyq.pyqautoconfig.PyqAutoConfigQuery;
import com.uzai.console.dto.pyq.pyqfollowcomment.PyqFollowCommentQuery;
import com.uzai.console.dto.pyq.pyqjob.PyqJobQuery;
import com.uzai.console.dto.sop.soptask.SopTaskQuery;
import com.uzai.console.dto.sysdomain.SysDomainQuery;
import com.uzai.console.dto.tb.tbtoken.TbTokenQuery;
import com.uzai.console.dto.vph.vphtoken.VphTokenQuery;
import com.uzai.console.dto.wechatprivate.devicewechatinfo.DeviceWechatInfoQuery;
import com.uzai.console.dto.wechatwork.devicewxworkinfo.DeviceWxworkInfoQuery;
import com.uzai.console.dto.wxqaddfriend.wxqaddfriendtask.WxqAddFriendTaskQuery;
import com.uzai.console.dto.wxqcontactrefresh.WxqContactRefreshQuery;
import com.uzai.console.dto.zombiefan.zombiefantask.ZombieFanTaskQuery;
import com.uzai.console.dto.zombiefanpassive.zombiefanpassivetask.ZombieFanPassiveTaskQuery;
import com.uzai.console.entity.*;
import com.uzai.console.enums.ContractStatusTypeEnum;
import com.uzai.console.enums.SopTaskStatusEnum;
import com.uzai.console.enums.WxqAddFriendTaskStatusEnum;
import com.uzai.console.enums.ZombieFanTaskStatusEnum;
import com.uzai.console.jsonvo.merbaseconfig.HandExpiredOrdersConfigJson;
import com.uzai.console.jsonvo.mini.AuthorizerAccessToken;
import com.uzai.console.mapper.*;
import com.uzai.console.service.alipaydetail.AlipayDetailService;
import com.uzai.console.service.dy.DyOrderSyncService;
import com.uzai.console.service.dy.DyTokenService;
import com.uzai.console.service.fd.FdAutoSendService;
import com.uzai.console.service.feign.ClientApiService;
import com.uzai.console.service.feign.UzaiBroadcastFeignService;
import com.uzai.console.service.feign.UzaiContractFeignService;
import com.uzai.console.service.feign.UzaiImClientFeignService;
import com.uzai.console.service.feign.dto.ContractOpeDto;
import com.uzai.console.service.jd.JdOrderSyncService;
import com.uzai.console.service.ks.KsOrderSyncService;
import com.uzai.console.service.kuizhan.KuaiZhanService;
import com.uzai.console.service.locallive.ElmOrderSyncService;
import com.uzai.console.service.locallive.MtOrderSyncService;
import com.uzai.console.service.md.mdactivity.MdActivityService;
import com.uzai.console.service.md.mdexchange.MdExchangeService;
import com.uzai.console.service.merchant.MerchantService;
import com.uzai.console.service.mini.MiniOptService;
import com.uzai.console.service.orderpull.OrderPullService;
import com.uzai.console.service.pdd.PddOrderSyncService;
import com.uzai.console.service.pyq.PyqAutoSendService;
import com.uzai.console.service.pyq.PyqJobService;
import com.uzai.console.service.ratelimit.RatelimitService;
import com.uzai.console.service.rocketmq.NoticeMsgPushProducerService;
import com.uzai.console.service.sop.SopTaskAddInfoService;
import com.uzai.console.service.sop.SopTaskSyncService;
import com.uzai.console.service.tb.tborder.TbOrderSyncService;
import com.uzai.console.service.tb.tbpunishorder.TbPunishOrderService;
import com.uzai.console.service.vph.VphOrderSyncService;
import com.uzai.console.service.wechatwork.DeviceWxworkInfoService;
import com.uzai.console.service.wwgroup.GroupCreateTaskService;
import com.uzai.console.service.wxqaddfriend.WxqAddFriendTaskAddInfoService;
import com.uzai.console.service.wxqcontactrefresh.WxqContactRefreshService;
import com.uzai.console.service.xxljob.XxlJobSyncService;
import com.uzai.console.service.zombiefan.ZombieFanTaskSendInfoService;
import com.uzai.console.service.zombiefanpassive.ZombieFanPassiveTaskService;
import com.uzai.console.vo.alarm.alarmevent.AlarmEventConfigVo;
import com.uzai.console.vo.alarm.alarmrule.AlarmRuleContentVo;
import com.uzai.console.vo.contract.ContractSignInfoVo;
import com.uzai.console.vo.deviceauth.DeviceAuthForWechantAndWxworkVo;
import com.uzai.console.vo.kuaizhan.GetSiteInfoVo;
import com.uzai.console.vo.sop.soptask.SopTaskQueryParaVo;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author liuqi
 * @date 2021年08月25日 20:17
 */
@Service
public class XxlJobSyncServiceImpl implements XxlJobSyncService {

    Logger logger = LoggerFactory.getLogger(XxlJobSyncServiceImpl.class);

    @Autowired
    private AlipayDetailMapper alipayDetailMapper;
    @Autowired
    private AlipayDetailService alipayDetailService;
    @Autowired
    private RatelimitService ratelimitService;
    @Autowired
    private DeviceAuthMapper deviceAuthMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private DeviceWechatInfoMapper deviceWechatInfoMapper;
    @Autowired
    private DeviceWxworkInfoMapper deviceWxworkInfoMapper;
    @Autowired
    private UzaiBroadcastFeignService uzaiBroadcastFeignService;
    @Autowired
    private AlarmRuleMapper alarmRuleMapper;
    @Autowired
    private PyqAutoConfigMapper pyqAutoConfigMapper;
    @Autowired
    private FdAutoConfigMapper fdAutoConfigMapper;
    @Autowired
    private FdAutoSendService fdAutoSendService;
    @Autowired
    private PyqAutoSendService pyqAutoSendService;
    @Autowired
    private PyqFollowCommentMapper pyqFollowCommentMapper;
    @Autowired
    private TbTokenMapper tbTokenMapper;
    @Autowired
    private PddTokenMapper pddTokenMapper;
    @Autowired
    private VphTokenMapper vphTokenMapper;
    @Autowired
    private TbPunishOrderService tbPunishOrderService;
    @Autowired
    private UzaiConsoleSysConfig uzaiConsoleSysConfig;
    @Autowired
    private MerBaseConfigMapper merBaseConfigMapper;
    @Autowired
    private TbOrderMapper tbOrderMapper;
    @Autowired
    private TbOrderSyncService tbOrderSyncService;
    @Autowired
    private JdOrderSyncService jdOrderSyncService;
    @Autowired
    private PddOrderSyncService pddOrderSyncService;
    @Autowired
    private VphOrderSyncService vphOrderSyncService;
    @Autowired
    private DyOrderSyncService dyOrderSyncService;
    @Autowired
    private MtOrderSyncService mtOrderSyncService;
    @Autowired
    private ElmOrderSyncService elmOrderSyncService;
    @Autowired
    private KsOrderSyncService ksOrderSyncService;
    @Autowired
    private FdGoodsParaMapper fdGoodsParaMapper;
    @Autowired
    private FdTemplateMapper fdTemplateMapper;
    @Autowired
    private SysPluginMapper sysPluginMapper;
    @Autowired
    private ConfigPlanMapper configPlanMapper;
    @Autowired
    private UzaiImClientFeignService uzaiImClientFeignService;
    @Autowired
    private DyTokenMapper dyTokenMapper;
    @Autowired
    private DyTokenService dyTokenService;
    @Autowired
    private NoticeMsgPushProducerService noticeMsgPushProducerService;
    @Autowired
    private ZombieFanTaskMapper zombieFanTaskMapper;
    @Autowired
    private ZombieFanTaskSendInfoService zombieFanTaskSendInfoService;
    @Autowired
    private MdActivityMapper mdActivityMapper;
    @Autowired
    private MdExchangeMapper mdExchangeMapper;
    @Autowired
    private MdGoodsMapper mdGoodsMapper;
    @Autowired
    private MdActivityService mdActivityService;
    @Autowired
    private MdExchangeService mdExchangeService;
    @Autowired
    private SysDomainMapper sysDomainMapper;
    @Autowired
    private KuaiZhanService kuaiZhanService;
    @Autowired
    private MerchantMapper merchantMapper;
    @Autowired
    private OrderPullMapper orderPullMapper;
    @Autowired
    private OrderPullService orderPullService;
    @Autowired
    private PyqJobMapper pyqJobMapper;
    @Autowired
    private PyqJobService pyqJobService;
    @Autowired
    private MerchantService merchantService;
    @Autowired
    private ElasticsearchUtilGroupMsg elasticsearchUtilGroupMsg;
    @Autowired
    private WxqAddFriendTaskMapper wxqAddFriendTaskMapper;
    @Autowired
    private WxqAddFriendTaskAddInfoService wxqAddFriendTaskAddInfoService;
    @Autowired
    private SopTaskMapper sopTaskMapper;
    @Autowired
    private SopTaskAddInfoService sopTaskAddInfoService;
    @Autowired
    private SopTaskSyncService sopTaskSyncService;
    @Autowired
    private FdSendJobMapper fdSendJobMapper;
    @Autowired
    private MiniOrderMapper miniOrderMapper;
    @Autowired
    private MiniComponentAuthMapper miniComponentAuthMapper;
    @Autowired
    private MiniOptService miniOptService;
    @Autowired
    private WxqContactRefreshMapper wxqContactRefreshMapper;
    @Autowired
    private WxqContactRefreshService wxqContactRefreshService;
    @Autowired
    private ZombieFanPassiveTaskMapper zombieFanPassiveTaskMapper;
    @Autowired
    private ZombieFanPassiveTaskService zombieFanPassiveTaskService;
    @Autowired
    private ZombieFanPassiveTaskSendInfoMapper zombieFanPassiveTaskSendInfoMapper;
    @Autowired
    private DingWarningGroupMapper dingWarningGroupMapper;
    @Autowired
    private DingWarningGroupDetailMapper dingWarningGroupDetailMapper;
    @Autowired
    private MerReportChangeMapper merReportChangeMapper;
    @Autowired
    private ClientApiService clientApiService;
    @Autowired
    private DeviceWxworkInfoService deviceWxworkInfoService;
    @Autowired
    private GroupCreateTaskService groupCreateTaskService;

    @Autowired
    private SysContractMapper sysContractMapper;

    @Autowired
    private UzaiContractFeignService uzaiContractFeignService;

    /**
     * 个人机器人掉线发送报警消息
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void deviceWechatOffLineAlarmMsg() {

        //限流key
        String taskLimitKet = "-deviceWechatOffLineAlarmMsg-taskLimitKey-";
        Object object = redisTemplate.opsForValue().get(taskLimitKet);
        if (object != null) {
            return;
        }
        //保存限流key
        redisTemplate.opsForValue().set(taskLimitKet, taskLimitKet, 30, TimeUnit.MINUTES);


        logger.info("-----调用个人微信设备掉线消息报警消息线程----");

        try {
            int now = DateUtil.getNowTime();

            //个人微信机器人是否掉线
            DeviceWechatInfoQuery deviceWechatInfoQuery = new DeviceWechatInfoQuery();

            //查询所有机器人
            Page<DeviceWechatInfo> page = new Page<>();
            page.setCurrent(1);//只查第一页
            page.setSize(10); //每页查询20个
            page.addOrder(OrderItem.asc("id"));//默认id升序
            Long idStart = 0L;

            List<DeviceWechatInfo> deviceWechatInfoList = deviceWechatInfoMapper.findSimpleByList(page, deviceWechatInfoQuery);

            //判断当天生效时间范围
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String day = sdf.format(new Date());

            while (deviceWechatInfoList != null && deviceWechatInfoList.size() > 0) {
                for (DeviceWechatInfo deviceWechatInfo : deviceWechatInfoList) {
                    if (deviceWechatInfo.getId().longValue() > idStart.longValue()) {
                        idStart = deviceWechatInfo.getId();
                    }

                    //限流判断(30秒内判断一次)
                    boolean inRateLimit = ratelimitService.inRateLimit("deviceWechatInfoOffLineAlarmMsg-" + deviceWechatInfo.getId(), 1, 30);
                    if (!inRateLimit) {
                        //logger.info("{}:inRateLimit false. deviceUniqueId=", deviceAuth.getDeviceUniqueId());
                        continue;
                    }

                    if (deviceWechatInfo.getDeviceId().equals("wxid_0v08u4pfnebf22")) {
                        logger.info("111");
                    }

                    //是否配置了报警规则
                    if (deviceWechatInfo.getAlarmRuleId() != null) {
                        AlarmRule alarmRule = alarmRuleMapper.selectById(deviceWechatInfo.getAlarmRuleId(), deviceWechatInfo.getMerId());
                        if (alarmRule != null && Tools.getInteger(alarmRule.getStatus()).intValue() == 1) { //报警规则开启才判断
                            //有效开始时间
                            String startTimeStr = day + " " + alarmRule.getStartTime() + ":00";
                            int startTime = DateUtil.getStrTime(startTimeStr);
                            //有效结束
                            String endTimeStr = day + " " + alarmRule.getEndTime() + ":00";
                            int endTime = DateUtil.getStrTime(endTimeStr);

                            //验证当前时间是否在有效时间之内，在之内才触发报警消息
                            if (now >= startTime && now <= endTime) {

                                //掉线标志
                                boolean offlineFlag_pc = false;     //pc端掉线标志
                                boolean offlineFlag_mobile = false; //移动端掉线标志

                                //电量不足标志
                                boolean batteryFlag_mobile = false; //移动端电量不足标志

                                //磁盘信息（用于磁盘报警）
                                boolean diskUsedFlag = false;      //系统磁盘不足标志
                                double diskTotal = 0.00D;          //总磁盘
                                double diskFree = 0.00D;           //可用磁盘
                                //设备话费余额报警
                                boolean phoneBalFlag = false;      //话费余额不足标志

                                //判断手机端在线，还是电脑端在线
                                int recvmsgType = Tools.getInteger(deviceWechatInfo.getRecvmsgType()).intValue();
                                if (recvmsgType == DeviceTypeEnum.DT_PC_WECHAT_VALUE) {//PC端在线
                                    //从缓存中换取个人微信PC端信息
                                    Object object_pc = redisTemplate.opsForValue().get(String.format(RedisCacheKeyEnum.DEVICE_INFO_WECHAT_PC.getKey(), deviceWechatInfo.getId()));
                                    DeviceInfoPcWeChatCacheDto deviceInfoPcWeChatCacheDto = JSONObject.parseObject(String.valueOf(object_pc), DeviceInfoPcWeChatCacheDto.class);
                                    //PC端个人微信信息不为空
                                    if (deviceInfoPcWeChatCacheDto != null) {
                                        //获取最新心跳时间
                                        Integer lastHeartBeatTime = deviceInfoPcWeChatCacheDto.getLastHeartBeatTime();
                                        if (lastHeartBeatTime != null) {
                                            //判断是否刚掉线（心跳时间在5分钟以外，且 少于 15天之内）
                                            if (now - lastHeartBeatTime.intValue() > Const.Device.HEART_BEAT_OFF_LINE_TIME.intValue() && now - lastHeartBeatTime.intValue() < 15 * 24 * 3600) {
                                                offlineFlag_pc = true;
                                            }
                                        }
                                        //获取最新的磁盘信息
                                        diskTotal = Tools.getDouble(deviceInfoPcWeChatCacheDto.getDiskTotal());
                                        diskFree = Tools.getDouble(deviceInfoPcWeChatCacheDto.getDiskFree());
                                    }
                                } else if (recvmsgType == DeviceTypeEnum.DT_ANDROID_WECHAT_VALUE) {//手机端在线
                                    //从缓存中获取个人微信手机端信息
                                    Object object_mobile = redisTemplate.opsForValue().get(String.format(RedisCacheKeyEnum.DEVICE_INFO_WECHAT_MOBLE.getKey(), deviceWechatInfo.getId()));
                                    DeviceInfoMobileWeChatCacheDto deviceInfoMobileWeChatCacheDto = JSONObject.parseObject(String.valueOf(object_mobile), DeviceInfoMobileWeChatCacheDto.class);
                                    //移动端个人微信信息不为空
                                    if (deviceInfoMobileWeChatCacheDto != null) {
                                        //获取最新心跳时间
                                        Integer lastHeartBeatTime = deviceInfoMobileWeChatCacheDto.getLastHeartBeatTime();
                                        if (lastHeartBeatTime != null) {
                                            //判断是否刚掉线（心跳时间在5分钟以外，且 少于 15天之内）
                                            if (now - lastHeartBeatTime.intValue() > Const.Device.HEART_BEAT_OFF_LINE_TIME.intValue() && now - lastHeartBeatTime.intValue() < 15 * 24 * 3600) {
                                                offlineFlag_mobile = true;
                                            }
                                            //判断在线（少于5分钟表示在线）
                                            if (now - lastHeartBeatTime < Const.Device.HEART_BEAT_OFF_LINE_TIME) {
                                                //获取最新的手机电量值
                                                Integer batteryLevel = deviceInfoMobileWeChatCacheDto.getBatteryLevel();
                                                if (batteryLevel != null) {
                                                    //判断电量（少于5分钟表示在线）
                                                    //报警规则里配置的报警值
                                                    Integer mobileBatteryEnergy = Tools.getInteger(alarmRule.getMobileBatteryEnergy());
                                                    if (batteryLevel.intValue() <= mobileBatteryEnergy.intValue()) {
                                                        batteryFlag_mobile = true; //低电量报警
                                                    }
                                                }
                                            }
                                        }

                                        //获取最新的磁盘信息
                                        diskTotal = Tools.getLong(deviceInfoMobileWeChatCacheDto.getSdCardTotal());
                                        diskFree = Tools.getLong(deviceInfoMobileWeChatCacheDto.getSdCardFree());
                                    }
                                }

                                //判断是否有报警规则-磁盘使用率报警/话费余额报警
                                if (StringUtils.isNotBlank(alarmRule.getRuleInfo())) {
                                    List<AlarmRuleContentVo> alarmRuleContentList = JSONObject.parseArray(alarmRule.getRuleInfo(), AlarmRuleContentVo.class);
                                    if (alarmRuleContentList != null && alarmRuleContentList.size() > 0) {
                                        for (AlarmRuleContentVo alarmRuleContentVo : alarmRuleContentList) {
                                            //系统
                                            if ("system".equals(alarmRuleContentVo.getSystemType())) {
                                                //磁盘使用率
                                                if ("disk".equals(alarmRuleContentVo.getAlarmType())) {
                                                    //报警规则设置的报警值
                                                    Integer averageRate = Tools.getInteger(alarmRuleContentVo.getAverageRate());
                                                    //判断系统总磁盘大于0才判断规则
                                                    if (diskTotal > 0.00D) {
                                                        //系统使用磁盘
                                                        double diskUsed = com.uzai.common.utils.Math.sub(diskTotal, diskFree);
                                                        //系统磁盘使用率(百分比)
                                                        double diskUsedRate = com.uzai.common.utils.Math.mul(com.uzai.common.utils.Math.div(diskUsed, diskTotal, 4), 100);
                                                        if (diskUsedRate >= averageRate.intValue()) {
                                                            diskUsedFlag = true;
                                                        }
                                                    }
                                                }
                                            } else if ("device".equals(alarmRuleContentVo.getSystemType())) { //设备
                                                //话费余额
                                                if ("phonebal".equals(alarmRuleContentVo.getAlarmType())) {
                                                    //报警规则设置的报警值
                                                    Integer averageRate = alarmRuleContentVo.getAverageRate();
                                                    if (averageRate != null) { //开启了话费余额
                                                        phoneBalFlag = true;
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }

                                //---下面依次处理各个报警信息----

                                //是否开启设备掉线报警
                                if (Tools.getInteger(alarmRule.getClientOut()).intValue() == 1) {
                                    //PC端和移动端只要一个掉线，就报警
                                    if (offlineFlag_pc || offlineFlag_mobile) {
                                        //您的客户端已退出，请及时检查，客户端id：${deviceid},机器人昵称：${devicename}
                                        AlarmMsgFeignDto alarmMsgFeignDto = new AlarmMsgFeignDto();
                                        alarmMsgFeignDto.setMerId(deviceWechatInfo.getMerId());
                                        alarmMsgFeignDto.setType(SysMsgTypeEnum.CLIENT_QUIT.getValue()); //客户端退出
                                        alarmMsgFeignDto.setDeviceUniqueId(deviceWechatInfo.getId());
                                        alarmMsgFeignDto.setDeviceType(DeviceTypeEnum.DT_PC_WECHAT.getKey());
                                        //消息
                                        JSONObject ext = new JSONObject();
                                        ext.put("deviceid", deviceWechatInfo.getDeviceId());
                                        ext.put("robotid", deviceWechatInfo.getDeviceId());
                                        String devicename = Tools.getStr(deviceWechatInfo.getDeviceName());
                                        //如果备注不为空，则加上（机器人备注）
                                        if (StringUtils.isNotBlank(deviceWechatInfo.getDeviceRemark())) {
                                            devicename = devicename + "(" + Tools.getStr(deviceWechatInfo.getDeviceRemark()) + ")";
                                        }
                                        ext.put("devicename", devicename);

                                        if (Tools.getInteger(deviceWechatInfo.getRecvmsgType()).intValue() == DeviceTypeEnum.DT_PC_WECHAT_VALUE) { //Pc端，需要增加ip
                                            String ip = Tools.findDeviceIpByRegex(deviceWechatInfo.getLastLoginIp());
                                            if (StringUtils.isNotBlank(ip)) {
                                                ext.put("content", "IP地址：" + ip);
                                            }
                                        }

                                        alarmMsgFeignDto.setExt(ext.toJSONString());
//                                        UzaiRespVo uzaiRespVo = uzaiBroadcastFeignService.sysMsgPush(alarmMsgFeignDto);
//                                        logger.info("---机器人下线报警消息-para={}, result={}", JSONObject.toJSONString(alarmMsgFeignDto), JSONObject.toJSONString(uzaiRespVo));

                                        //2024-01-09修改成直接发送MQ
                                        noticeMsgPushProducerService.sendSysAlarmMsgAsync(alarmMsgFeignDto);
                                    }
                                }

                                //是否开启移动设备电量不足报警
                                if (Tools.getInteger(alarmRule.getMobileBattery()).intValue() == 1) {
                                    if (batteryFlag_mobile) {
                                        //您的手机电量过低，请及时处理！报警设备id：${deviceid},机器人昵称：${name}
                                        AlarmMsgFeignDto alarmMsgFeignDto = new AlarmMsgFeignDto();
                                        alarmMsgFeignDto.setMerId(deviceWechatInfo.getMerId());
                                        alarmMsgFeignDto.setType(SysMsgTypeEnum.MOBILE_BATTERY.getValue()); //手机电量过低
                                        alarmMsgFeignDto.setDeviceUniqueId(deviceWechatInfo.getId());
                                        alarmMsgFeignDto.setDeviceType(DeviceTypeEnum.DT_ANDROID_WECHAT.getKey());
                                        //消息
                                        JSONObject ext = new JSONObject();
                                        ext.put("deviceid", deviceWechatInfo.getDeviceId());
                                        String devicename = Tools.getStr(deviceWechatInfo.getDeviceName());
                                        //如果备注不为空，则加上（机器人备注）
                                        if (StringUtils.isNotBlank(deviceWechatInfo.getDeviceRemark())) {
                                            devicename = devicename + "(" + Tools.getStr(deviceWechatInfo.getDeviceRemark()) + ")";
                                        }
                                        ext.put("name", devicename);
                                        ext.put("number", Tools.getInteger(alarmRule.getMobileBatteryEnergy())); //电量报警值参数
                                        alarmMsgFeignDto.setExt(ext.toJSONString());
//                                        UzaiRespVo uzaiRespVo = uzaiBroadcastFeignService.sysMsgPush(alarmMsgFeignDto);
//                                        logger.info("---机器人手机电量过低报警消息-para={}, result={}", JSONObject.toJSONString(alarmMsgFeignDto), JSONObject.toJSONString(uzaiRespVo));
                                        //2024-01-09修改成直接发送MQ
                                        noticeMsgPushProducerService.sendSysAlarmMsgAsync(alarmMsgFeignDto);
                                    }
                                }

                                //是否发送系统磁盘使用率报警
                                if (diskUsedFlag) {
                                    //您的手机电量过低，请及时处理！报警设备id：${deviceid},机器人昵称：${name}
                                    AlarmMsgFeignDto alarmMsgFeignDto = new AlarmMsgFeignDto();
                                    alarmMsgFeignDto.setMerId(deviceWechatInfo.getMerId());
                                    alarmMsgFeignDto.setType(SysMsgTypeEnum.CPU_MEMORY.getValue()); //CPU/内存/磁盘剩余空间不足报警
                                    alarmMsgFeignDto.setDeviceUniqueId(deviceWechatInfo.getId());
                                    alarmMsgFeignDto.setDeviceType(DeviceTypeEnum.DT_PC_WECHAT.getKey());
                                    //消息
                                    JSONObject ext = new JSONObject();
                                    ext.put("deviceid", deviceWechatInfo.getDeviceId());
                                    String devicename = Tools.getStr(deviceWechatInfo.getDeviceName());
                                    //如果备注不为空，则加上（机器人备注）
                                    if (StringUtils.isNotBlank(deviceWechatInfo.getDeviceRemark())) {
                                        devicename = devicename + "(" + Tools.getStr(deviceWechatInfo.getDeviceRemark()) + ")";
                                    }
                                    ext.put("devicename", devicename);
                                    ext.put("content", "系统磁盘使用率过高");
                                    alarmMsgFeignDto.setExt(ext.toJSONString());
//                                    UzaiRespVo uzaiRespVo = uzaiBroadcastFeignService.sysMsgPush(alarmMsgFeignDto);
//                                    logger.info("---系统磁盘使用率过高-para={}, result={}", JSONObject.toJSONString(alarmMsgFeignDto), JSONObject.toJSONString(uzaiRespVo));

                                    //2024-01-09修改成直接发送MQ
                                    noticeMsgPushProducerService.sendSysAlarmMsgAsync(alarmMsgFeignDto);
                                }

                                //是否开启话费余额报警，如果开启了，则需要发送请求查询话费余额接口
//                            if(phoneBalFlag){
//                                if(StringUtils.isNotBlank(deviceWechatInfo.getMobile()) && deviceWechatInfo.getMobiletype() != null){ //机器人必须有手机号才能发送查询话费
//                                    //一天只查询一次（判断上次发送时间是否跟当前时间是否是同一天）
//                                    Integer sendTime = Tools.getInteger(deviceWechatInfo.getSendTime());
//                                    if(sendTime == 0 || !(DateUtil.isSameDay(new Date(sendTime * 1000L), new Date()))){//一次都没发送过或者不是同一天，则发送请求话费余额查询
//                                        //发送请求查询话费余额指令
//                                        MsgDto<SendSmsReqProtoc> msgDto = new MsgDto<>();
//                                        SendSmsReqProtoc sendSmsReqProtoc = new SendSmsReqProtoc();
//                                        if(deviceWechatInfo.getMobiletype().intValue() == 0){ //电信
//                                            sendSmsReqProtoc.setSendMobile("10001");
//                                            sendSmsReqProtoc.setContent("101");
//                                        }else if(deviceWechatInfo.getMobiletype().intValue() == 1){//移动
//                                            sendSmsReqProtoc.setSendMobile("10086");
//                                            sendSmsReqProtoc.setContent("101");
//                                        }else if(deviceWechatInfo.getMobiletype().intValue() == 2){//联通
//                                            sendSmsReqProtoc.setSendMobile("10010");
//                                            sendSmsReqProtoc.setContent("话费查询");
//                                        }
//                                        msgDto.setContent(sendSmsReqProtoc);
//                                        msgDto.setId(IdWorker.getId());
//                                        msgDto.setDeviceType(deviceWechatInfo.getRecvmsgType());
//                                        msgDto.setDeviceUniqueId(deviceWechatInfo.getId());
//                                        msgDto.setMerId(deviceWechatInfo.getMerId());
//                                        msgDto.setMsgType(MessageFuncEnum.SEND_SMS.getValue());
//                                        noticeMsgPushProducerService.sendQueryPhoneBal(msgDto);
//
//                                        //修改此机器人的发送时间
//                                        deviceWechatInfo.setSendTime(now);
//                                        deviceWechatInfoMapper.updateById(deviceWechatInfo);
//                                    }
//                                }
//                            }
                            }
                        }
                    }

                    //2023-04-04修改，增加清除手机端缓存（配置方案中本地设置-客户端设置）
                    //从配置方案中获取是否清除手机端缓存
                    if (Tools.getInteger(deviceWechatInfo.getRecvmsgType()).intValue() == DeviceTypeEnum.DT_ANDROID_WECHAT_VALUE) {
                        if (deviceWechatInfo.getConfigId() != null) {
                            ConfigPlan configPlan = configPlanMapper.selectById(deviceWechatInfo.getConfigId(), deviceWechatInfo.getMerId());
                            if (configPlan.getClientSetId() != null) {
                                SysPlugin sysPlugin = sysPluginMapper.selectById(configPlan.getClientSetId(), configPlan.getMerId());
                                if (sysPlugin != null && StringUtils.isNotBlank(sysPlugin.getData())) {
                                    try {
                                        JSONObject jsonObject = JSONObject.parseObject(sysPlugin.getData());
                                        if (jsonObject != null) {
                                            //是否开启每天定时清理任务
                                            Integer per_day_clean_flag = Tools.getInteger(jsonObject.getInteger("per_day_clean_flag"));
                                            if (per_day_clean_flag.intValue() == 1) { //开启
                                                //是否开启每天定时清理任务
                                                String pey_day_clean_time = jsonObject.getString("pey_day_clean_time");
                                                if (StringUtils.isBlank(pey_day_clean_time)) {
                                                    pey_day_clean_time = "00:00:00";
                                                }
                                                //定时清理缓存时间
                                                pey_day_clean_time = day + " " + pey_day_clean_time;
                                                int cleanCacheTime = DateUtil.getStrTime(pey_day_clean_time);
                                                //清理时间大于现在时间，且与现在时间只差10分钟之内才清除
                                                if (cleanCacheTime > now && cleanCacheTime - now < 600) {
                                                    //开启任何一个都发送清理请求
                                                    List<Integer> actions = new ArrayList<>();
                                                    //清理移动端微信缓存
                                                    Integer clean_mobile_wechat_cache = Tools.getInteger(jsonObject.getInteger("clean_mobile_wechat_cache"));
                                                    if (clean_mobile_wechat_cache.intValue() == 1) {
                                                        actions.add(MobilePhoneActionEnums.CleanWxCache.getValue());
                                                    }
                                                    //清理移动端图片缓存
                                                    Integer clean_mobile_pic_cache = Tools.getInteger(jsonObject.getInteger("clean_mobile_pic_cache"));
                                                    if (clean_mobile_pic_cache.intValue() == 1) {
                                                        actions.add(MobilePhoneActionEnums.CleanAppCache.getValue());
                                                    }

                                                    //只要有开启选项，则发送消息
                                                    if (actions != null && actions.size() > 0) {
                                                        MsgDto<ClearDeviceCacheDto> msgDto = new MsgDto<>();
                                                        ClearDeviceCacheDto clearDeviceCacheDto = new ClearDeviceCacheDto();
                                                        msgDto.setContent(clearDeviceCacheDto);
                                                        msgDto.setId(IdWorker.getId());
                                                        msgDto.setDeviceUniqueId(deviceWechatInfo.getId());
                                                        msgDto.setDeviceType(deviceWechatInfo.getRecvmsgType());
                                                        msgDto.setMerId(deviceWechatInfo.getMerId());
                                                        msgDto.setMsgType(MessageFuncEnum.CLEAR_DEVICE_CACHE_VALUE.getValue());
                                                        clearDeviceCacheDto.setDeviceId(deviceWechatInfo.getDeviceId());
                                                        clearDeviceCacheDto.setImei(deviceWechatInfo.getDeviceId());
                                                        clearDeviceCacheDto.setActions(actions);
                                                        UzaiRespVo<Object> uzaiRespVo = uzaiImClientFeignService.cleanDeviceCache(msgDto);
                                                        logger.info("--调用发送清除个微设备移动端缓存--para={},result={}", JSONObject.toJSONString(msgDto), JSONObject.toJSONString(uzaiRespVo));
                                                    }
                                                }
                                            }
                                        }
                                    } catch (Exception e) {
                                        logger.info("--发送清除个微设备移动端缓存失败--error={}", e.getMessage());
                                    }
                                }
                            }
                        }
                    }
                }

                deviceWechatInfoQuery.setIdStart(idStart);
                deviceWechatInfoList = deviceWechatInfoMapper.findSimpleByList(page, deviceWechatInfoQuery);
            }
        } catch (Exception e) {
            logger.info(e.getMessage());
        } finally {
            //删除限流key
            redisTemplate.delete(taskLimitKet);
        }
    }

    /**
     * 企业机器人掉线发送报警消息
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void deviceWxworkInfoOffLineAlarmMsg() {

        //限流key
        String taskLimitKet = "-deviceWxworkInfoOffLineAlarmMsg-taskLimitKey-";
        Object object = redisTemplate.opsForValue().get(taskLimitKet);
        if (object != null) {
            return;
        }
        //保存限流key
        redisTemplate.opsForValue().set(taskLimitKet, taskLimitKet, 30, TimeUnit.MINUTES);

        logger.info("-----调用企业微信设备掉线消息报警消息线程----");

        try {
            int now = DateUtil.getNowTime();

            //个人微信机器人是否掉线
            DeviceWxworkInfoQuery deviceWxworkInfoQuery = new DeviceWxworkInfoQuery();

            //查询所有机器人
            Page<DeviceWxworkInfo> page = new Page<>();
            page.setCurrent(1);//只查第一页
            page.setSize(10); //每页查询20个
            page.addOrder(OrderItem.asc("id"));//默认id升序
            Long idStart = 0L;

            List<DeviceWxworkInfo> deviceWxworkInfoList = deviceWxworkInfoMapper.findSimpleByList(page, deviceWxworkInfoQuery);

            //判断当天生效时间范围
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String day = sdf.format(new Date());

            while (deviceWxworkInfoList != null && deviceWxworkInfoList.size() > 0) {
                for (DeviceWxworkInfo deviceWxworkInfo : deviceWxworkInfoList) {
                    if (deviceWxworkInfo.getId().longValue() > idStart.longValue()) {
                        idStart = deviceWxworkInfo.getId();
                    }

                    //限流判断(30秒内判断一次)
                    boolean inRateLimit = ratelimitService.inRateLimit("deviceWxworkInfoOffLineAlarmMsg-" + deviceWxworkInfo.getId(), 1, 30);
                    if (!inRateLimit) {
                        //logger.info("{}:inRateLimit false. deviceUniqueId=", deviceAuth.getDeviceUniqueId());
                        continue;
                    }

                    if (deviceWxworkInfo.getAlarmRuleId() != null) {
                        AlarmRule alarmRule = alarmRuleMapper.selectById(deviceWxworkInfo.getAlarmRuleId(), deviceWxworkInfo.getMerId());
                        if (alarmRule != null && Tools.getInteger(alarmRule.getStatus()).intValue() == 1) { //报警规则开启才判断
                            //是否开启设备掉线报警
                            if (Tools.getInteger(alarmRule.getClientOut()).intValue() == 1) {

                                //有效开始时间
                                String startTimeStr = day + " " + alarmRule.getStartTime() + ":00";
                                int startTime = DateUtil.getStrTime(startTimeStr);
                                //有效结束
                                String endTimeStr = day + " " + alarmRule.getEndTime() + ":00";
                                int endTime = DateUtil.getStrTime(endTimeStr);

                                //验收当前时间是否在有效时间之内，在之内才触发报警消息
                                if (now >= startTime && now <= endTime) {
                                    //掉线标志
                                    boolean offlineFlag_pc = false;     //pc端掉线标志
                                    boolean offlineFlag_mobile = false; //移动端掉线标志

                                    //电量不足标志
                                    boolean batteryFlag_mobile = false; //移动端电量不足标志

                                    //磁盘信息（用于磁盘报警）
                                    boolean diskUsedFlag = false;      //系统磁盘不足标志
                                    double diskTotal = 0.00D;          //总磁盘
                                    double diskFree = 0.00D;           //可用磁盘


                                    //判断手机端在线，还是电脑端在线
                                    int recvmsgType = Tools.getInteger(deviceWxworkInfo.getRecvmsgType()).intValue();
                                    if (recvmsgType == DeviceTypeEnum.DT_WORK_WECHAT_VALUE) {//PC端在线
                                        //从缓存中换取企业微信PC端信息
                                        Object object_pc = redisTemplate.opsForValue().get(String.format(RedisCacheKeyEnum.DEVICE_INFO_WXWORK.getKey(), deviceWxworkInfo.getId()));
                                        DeviceInfoWxWorkCacheDto deviceInfoWxWorkCacheDto = JSONObject.parseObject(String.valueOf(object_pc), DeviceInfoWxWorkCacheDto.class);
                                        //PC端个人微信信息不为空
                                        if (deviceInfoWxWorkCacheDto != null) {
                                            //获取最新心跳时间
                                            Integer lastHeartBeatTime = deviceInfoWxWorkCacheDto.getLastHeartBeatTime();
                                            if (lastHeartBeatTime != null) {
                                                //判断是否刚掉线（心跳时间在5分钟以外，且 少于 15天之内）
                                                if (now - lastHeartBeatTime.intValue() > Const.Device.HEART_BEAT_OFF_LINE_TIME.intValue() && now - lastHeartBeatTime.intValue() < 15 * 24 * 3600) {
                                                    offlineFlag_pc = true;
                                                }
                                            }
                                            //获取最新的磁盘信息
                                            diskTotal = Tools.getDouble(deviceInfoWxWorkCacheDto.getDiskTotal());
                                            diskFree = Tools.getDouble(deviceInfoWxWorkCacheDto.getDiskFree());
                                        }
                                    } else if (recvmsgType == DeviceTypeEnum.DT_ANDROID_WORK_WECHAT_VALUE) {//手机端在线
                                        //从缓存中获取个人微信手机端信息
                                        Object object_mobile = redisTemplate.opsForValue().get(String.format(RedisCacheKeyEnum.DEVICE_INFO_WXWORK_MOBLE.getKey(), deviceWxworkInfo.getId()));
                                        DeviceInfoMobileWxWorkCacheDto deviceInfoMobileWxWorkCacheDto = JSONObject.parseObject(String.valueOf(object_mobile), DeviceInfoMobileWxWorkCacheDto.class);
                                        //移动端个人微信信息不为空
                                        if (deviceInfoMobileWxWorkCacheDto != null) {
                                            //获取最新心跳时间
                                            Integer lastHeartBeatTime = deviceInfoMobileWxWorkCacheDto.getLastHeartBeatTime();
                                            if (lastHeartBeatTime != null) {
                                                //判断是否刚掉线（心跳时间在5分钟以外，且 少于 15天之内）
                                                if (now - lastHeartBeatTime.intValue() > Const.Device.HEART_BEAT_OFF_LINE_TIME.intValue() && now - lastHeartBeatTime.intValue() < 15 * 24 * 3600) {
                                                    offlineFlag_mobile = true;
                                                }
                                                //判断在线（少于5分钟表示在线）
                                                if (now - lastHeartBeatTime < Const.Device.HEART_BEAT_OFF_LINE_TIME) {
                                                    //获取最新的手机电量值
                                                    Integer batteryLevel = deviceInfoMobileWxWorkCacheDto.getBatteryLevel();
                                                    if (batteryLevel != null) {
                                                        //判断电量（少于5分钟表示在线）
                                                        //报警规则里配置的报警值
                                                        Integer mobileBatteryEnergy = Tools.getInteger(alarmRule.getMobileBatteryEnergy());
                                                        if (batteryLevel.intValue() <= mobileBatteryEnergy.intValue()) {
                                                            batteryFlag_mobile = true; //低电量报警
                                                        }
                                                    }
                                                }
                                            }

                                            //获取最新的磁盘信息
                                            diskTotal = Tools.getLong(deviceInfoMobileWxWorkCacheDto.getSdCardTotal());
                                            diskFree = Tools.getLong(deviceInfoMobileWxWorkCacheDto.getSdCardFree());
                                        }
                                    }

                                    //判断是否有报警规则-磁盘使用率报警
                                    if (StringUtils.isNotBlank(alarmRule.getRuleInfo())) {
                                        List<AlarmRuleContentVo> alarmRuleContentList = JSONObject.parseArray(alarmRule.getRuleInfo(), AlarmRuleContentVo.class);
                                        if (alarmRuleContentList != null && alarmRuleContentList.size() > 0) {
                                            for (AlarmRuleContentVo alarmRuleContentVo : alarmRuleContentList) {
                                                //系统
                                                if ("system".equals(alarmRuleContentVo.getSystemType())) {
                                                    //磁盘使用率
                                                    if ("disk".equals(alarmRuleContentVo.getAlarmType())) {
                                                        //报警规则设置的报警值
                                                        Integer averageRate = Tools.getInteger(alarmRuleContentVo.getAverageRate());
                                                        //判断系统总磁盘大于0才判断规则
                                                        if (diskTotal > 0.00D) {
                                                            //系统使用磁盘
                                                            double diskUsed = com.uzai.common.utils.Math.sub(diskTotal, diskFree);
                                                            //系统磁盘使用率(百分比)
                                                            double diskUsedRate = com.uzai.common.utils.Math.mul(com.uzai.common.utils.Math.div(diskUsed, diskTotal, 4), 100);
                                                            if (diskUsedRate >= averageRate.intValue()) {
                                                                diskUsedFlag = true;
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }

                                    //---下面依次处理各个报警信息----

                                    //是否开启设备掉线报警
                                    if (Tools.getInteger(alarmRule.getClientOut()).intValue() == 1) {
                                        //机器人不在线，则发送机器人掉线报警消息
                                        //PC端和移动端只要一个掉线，就报警
                                        if (offlineFlag_pc || offlineFlag_mobile) {
                                            //您的客户端已退出，请及时检查，客户端id：${deviceid},机器人昵称：${devicename}
                                            AlarmMsgFeignDto alarmMsgFeignDto = new AlarmMsgFeignDto();
                                            alarmMsgFeignDto.setMerId(deviceWxworkInfo.getMerId());
                                            alarmMsgFeignDto.setType(SysMsgTypeEnum.CLIENT_QUIT.getValue()); //客户端退出
                                            alarmMsgFeignDto.setDeviceUniqueId(deviceWxworkInfo.getId());
                                            alarmMsgFeignDto.setDeviceType(DeviceTypeEnum.DT_WORK_WECHAT.getKey());
                                            //消息
                                            JSONObject ext = new JSONObject();
                                            ext.put("deviceid", deviceWxworkInfo.getDeviceId());
                                            ext.put("robotid", deviceWxworkInfo.getDeviceId());
                                            String devicename = Tools.getStr(deviceWxworkInfo.getDeviceName());
                                            //如果备注不为空，则加上（机器人备注）
                                            if (StringUtils.isNotBlank(deviceWxworkInfo.getDeviceRemark())) {
                                                devicename = devicename + "(" + Tools.getStr(deviceWxworkInfo.getDeviceRemark()) + ")";
                                            }
                                            ext.put("devicename", devicename);

                                            if (Tools.getInteger(deviceWxworkInfo.getRecvmsgType()).intValue() == DeviceTypeEnum.DT_WORK_WECHAT_VALUE) { //Pc端，需要增加ip
                                                String ip = Tools.findDeviceIpByRegex(deviceWxworkInfo.getLastLoginIp());
                                                if (StringUtils.isNotBlank(ip)) {
                                                    ext.put("content", "IP地址：" + ip);
                                                }
                                            }

                                            alarmMsgFeignDto.setExt(ext.toJSONString());
//                                            UzaiRespVo uzaiRespVo = uzaiBroadcastFeignService.sysMsgPush(alarmMsgFeignDto);
//                                            logger.info("---机器人下线报警消息-para={}, result={}", JSONObject.toJSONString(alarmMsgFeignDto), JSONObject.toJSONString(uzaiRespVo));
                                            //2024-01-09修改成直接发送MQ
                                            noticeMsgPushProducerService.sendSysAlarmMsgAsync(alarmMsgFeignDto);
                                        }
                                    }

                                    //是否开启移动设备电量不足报警
                                    if (Tools.getInteger(alarmRule.getMobileBattery()).intValue() == 1) {
                                        if (batteryFlag_mobile) {
                                            //您的手机电量过低，请及时处理！报警设备id：${deviceid},机器人昵称：${name}
                                            AlarmMsgFeignDto alarmMsgFeignDto = new AlarmMsgFeignDto();
                                            alarmMsgFeignDto.setMerId(deviceWxworkInfo.getMerId());
                                            alarmMsgFeignDto.setType(SysMsgTypeEnum.MOBILE_BATTERY.getValue()); //手机电量过低
                                            alarmMsgFeignDto.setDeviceUniqueId(deviceWxworkInfo.getId());
                                            alarmMsgFeignDto.setDeviceType(DeviceTypeEnum.DT_ANDROID_WORK_WECHAT.getKey());
                                            //消息
                                            JSONObject ext = new JSONObject();
                                            ext.put("deviceid", deviceWxworkInfo.getDeviceId());
                                            String devicename = Tools.getStr(deviceWxworkInfo.getDeviceName());
                                            //如果备注不为空，则加上（机器人备注）
                                            if (StringUtils.isNotBlank(deviceWxworkInfo.getDeviceRemark())) {
                                                devicename = devicename + "(" + Tools.getStr(deviceWxworkInfo.getDeviceRemark()) + ")";
                                            }
                                            ext.put("name", devicename);
                                            ext.put("number", Tools.getInteger(alarmRule.getMobileBatteryEnergy())); //电量报警值参数
                                            alarmMsgFeignDto.setExt(ext.toJSONString());
//                                            UzaiRespVo uzaiRespVo = uzaiBroadcastFeignService.sysMsgPush(alarmMsgFeignDto);
//                                            logger.info("---机器人手机电量过低报警消息-para={}, result={}", JSONObject.toJSONString(alarmMsgFeignDto), JSONObject.toJSONString(uzaiRespVo));
                                            //2024-01-09修改成直接发送MQ
                                            noticeMsgPushProducerService.sendSysAlarmMsgAsync(alarmMsgFeignDto);
                                        }
                                    }

                                    //是否发送系统磁盘使用率报警
                                    if (diskUsedFlag) {
                                        //您的手机电量过低，请及时处理！报警设备id：${deviceid},机器人昵称：${name}
                                        AlarmMsgFeignDto alarmMsgFeignDto = new AlarmMsgFeignDto();
                                        alarmMsgFeignDto.setMerId(deviceWxworkInfo.getMerId());
                                        alarmMsgFeignDto.setType(SysMsgTypeEnum.CPU_MEMORY.getValue()); //CPU/内存/磁盘剩余空间不足报警
                                        alarmMsgFeignDto.setDeviceUniqueId(deviceWxworkInfo.getId());
                                        alarmMsgFeignDto.setDeviceType(DeviceTypeEnum.DT_WORK_WECHAT.getKey());
                                        //消息
                                        JSONObject ext = new JSONObject();
                                        ext.put("deviceid", deviceWxworkInfo.getDeviceId());
                                        String devicename = Tools.getStr(deviceWxworkInfo.getDeviceName());
                                        //如果备注不为空，则加上（机器人备注）
                                        if (StringUtils.isNotBlank(deviceWxworkInfo.getDeviceRemark())) {
                                            devicename = devicename + "(" + Tools.getStr(deviceWxworkInfo.getDeviceRemark()) + ")";
                                        }
                                        ext.put("devicename", devicename);
                                        ext.put("content", "系统磁盘使用率过高");
                                        alarmMsgFeignDto.setExt(ext.toJSONString());
//                                        UzaiRespVo uzaiRespVo = uzaiBroadcastFeignService.sysMsgPush(alarmMsgFeignDto);
//                                        logger.info("---系统磁盘使用率过高-para={}, result={}", JSONObject.toJSONString(alarmMsgFeignDto), JSONObject.toJSONString(uzaiRespVo));

                                        //2024-01-09修改成直接发送MQ
                                        noticeMsgPushProducerService.sendSysAlarmMsgAsync(alarmMsgFeignDto);
                                    }

                                }
                            }
                        }
                    }

                    //2024-01-12修改，增加清除手机端缓存（配置方案中本地设置-客户端设置）
                    //从配置方案中获取是否清除手机端缓存
                    if (Tools.getInteger(deviceWxworkInfo.getRecvmsgType()).intValue() == DeviceTypeEnum.DT_ANDROID_WORK_WECHAT_VALUE) {
                        if (deviceWxworkInfo.getConfigId() != null) {
                            ConfigPlan configPlan = configPlanMapper.selectById(deviceWxworkInfo.getConfigId(), deviceWxworkInfo.getMerId());
                            if (configPlan.getClientSetId() != null) {
                                SysPlugin sysPlugin = sysPluginMapper.selectById(configPlan.getClientSetId(), configPlan.getMerId());
                                if (sysPlugin != null && StringUtils.isNotBlank(sysPlugin.getData())) {
                                    try {
                                        JSONObject jsonObject = JSONObject.parseObject(sysPlugin.getData());
                                        if (jsonObject != null) {
                                            //是否开启每天定时清理任务
                                            Integer per_day_clean_flag = Tools.getInteger(jsonObject.getInteger("per_day_clean_flag"));
                                            if (per_day_clean_flag.intValue() == 1) { //开启
                                                //是否开启每天定时清理任务
                                                String pey_day_clean_time = jsonObject.getString("pey_day_clean_time");
                                                if (StringUtils.isBlank(pey_day_clean_time)) {
                                                    pey_day_clean_time = "00:00:00";
                                                }
                                                //定时清理缓存时间
                                                pey_day_clean_time = day + " " + pey_day_clean_time;
                                                int cleanCacheTime = DateUtil.getStrTime(pey_day_clean_time);
                                                //清理时间大于现在时间，且与现在时间只差10分钟之内才清除
                                                if (cleanCacheTime > now && cleanCacheTime - now < 600) {
                                                    //开启任何一个都发送清理请求
                                                    List<Integer> actions = new ArrayList<>();
                                                    //清理移动端微信缓存
                                                    Integer clean_mobile_wechat_cache = Tools.getInteger(jsonObject.getInteger("clean_mobile_wechat_cache"));
                                                    if (clean_mobile_wechat_cache.intValue() == 1) {
                                                        actions.add(MobilePhoneActionEnums.CleanWxCache.getValue());
                                                    }
                                                    //清理移动端图片缓存
                                                    Integer clean_mobile_pic_cache = Tools.getInteger(jsonObject.getInteger("clean_mobile_pic_cache"));
                                                    if (clean_mobile_pic_cache.intValue() == 1) {
                                                        actions.add(MobilePhoneActionEnums.CleanAppCache.getValue());
                                                    }

                                                    //只要有开启选项，则发送消息
                                                    if (actions != null && actions.size() > 0) {
                                                        MsgDto<ClearDeviceCacheDto> msgDto = new MsgDto<>();
                                                        ClearDeviceCacheDto clearDeviceCacheDto = new ClearDeviceCacheDto();
                                                        msgDto.setContent(clearDeviceCacheDto);
                                                        msgDto.setId(IdWorker.getId());
                                                        msgDto.setDeviceUniqueId(deviceWxworkInfo.getId());
                                                        msgDto.setDeviceType(deviceWxworkInfo.getRecvmsgType());
                                                        msgDto.setMerId(deviceWxworkInfo.getMerId());
                                                        msgDto.setMsgType(MessageFuncEnum.CLEAR_DEVICE_CACHE_VALUE.getValue());
                                                        clearDeviceCacheDto.setDeviceId(deviceWxworkInfo.getDeviceId());
                                                        clearDeviceCacheDto.setImei(deviceWxworkInfo.getDeviceId());
                                                        clearDeviceCacheDto.setActions(actions);
                                                        UzaiRespVo<Object> uzaiRespVo = uzaiImClientFeignService.cleanDeviceCache(msgDto);
                                                        logger.info("--调用发送清除企微移动端缓存--para={},result={}", JSONObject.toJSONString(msgDto), JSONObject.toJSONString(uzaiRespVo));
                                                    }
                                                }
                                            }
                                        }
                                    } catch (Exception e) {
                                        logger.info("--发送清除企微移动端缓存失败--error", e.getMessage());
                                    }
                                }
                            }
                        }
                    }


                }

                deviceWxworkInfoQuery.setIdStart(idStart);
                deviceWxworkInfoList = deviceWxworkInfoMapper.findSimpleByList(page, deviceWxworkInfoQuery);
            }
        } catch (Exception e) {
            logger.info(e.getMessage());
        } finally {
            //删除限流key
            redisTemplate.delete(taskLimitKet);
        }
    }

    /**
     * 个人微信机器人授权功能到期发送报警消息
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void deviceWechatExpiredAlarmMsg() {
        //限流key
        String taskLimitKet = "-deviceWechatExpiredAlarmMsg-taskLimitKey-";
        Object object = redisTemplate.opsForValue().get(taskLimitKet);
        if (object != null) {
            return;
        }
        //保存限流key
        redisTemplate.opsForValue().set(taskLimitKet, taskLimitKet, 30, TimeUnit.MINUTES);

        logger.info("-----调用个人机器人授权功能到期发送报警消息线程----");

        try {
            int now = DateUtil.getNowTime();
            //已经到期
            DeviceAuthQuery deviceAuthQuery_expired = new DeviceAuthQuery();
            deviceAuthQuery_expired.setDeviceType(DeviceTypeEnum.DT_PC_WECHAT.getKey());
            //只搜索到期15天之内的授权
            //int expireTimeStart = now - 15 * 24 * 3600;
            //只搜索未到期的授权
            int expireTimeStart = now;
            deviceAuthQuery_expired.setExpireTimeStart(expireTimeStart);
            //将要到期7天之内的授权
            int queryEndTime = now + 7 * 24 * 3600;
            deviceAuthQuery_expired.setExpireTimeEnd(queryEndTime);

            //查询机器人已经到期
            Page<DeviceAuth> page = new Page<>();
            page.setCurrent(1);//只查第一页
            page.setSize(10); //每页查询10个
            page.addOrder(OrderItem.asc("id"));//默认id升序
            Long idStart = 0L;

            List<DeviceAuth> deviceAuthList_expired = deviceAuthMapper.findByList(page, deviceAuthQuery_expired);
            while (deviceAuthList_expired != null && deviceAuthList_expired.size() > 0) {
                for (DeviceAuth deviceAuth : deviceAuthList_expired) {

                    //封号转名片不处理
                    if (deviceAuth.getProductCode().equals(ProductKeyEnum.BANTRANSFER.getValue())) {
                        continue;
                    }

                    if (deviceAuth.getId().longValue() > idStart.longValue()) {
                        idStart = deviceAuth.getId();
                    }
                    //到期15天和即将7天到期之内的授权才处理
                    if (deviceAuth.getExpireTime().intValue() >= expireTimeStart && deviceAuth.getExpireTime().intValue() <= queryEndTime) {

                        //限流判断(30秒内判断一次)
                        boolean inRateLimit = ratelimitService.inRateLimit("deviceWechatExpiredAlarmMsg-" + deviceAuth.getId(), 1, 30);
                        if (!inRateLimit) {
                            //logger.info("---inRateLimit false. deviceUniqueId={}", deviceAuth.getDeviceUniqueId());
                            continue;
                        }
                        DeviceWechatInfo deviceWechatInfo = deviceWechatInfoMapper.selectByDeviceId(deviceAuth.getDeviceId());
                        if (deviceWechatInfo != null && deviceWechatInfo.getAlarmRuleId() != null) {
                            AlarmRule alarmRule = alarmRuleMapper.selectById(deviceWechatInfo.getAlarmRuleId(), deviceWechatInfo.getMerId());
                            if (alarmRule != null && Tools.getInteger(alarmRule.getStatus()).intValue() == 1) { //报警规则开启才判断
                                //是否产品到期报警
                                if (Tools.getInteger(alarmRule.getProductExpired()).intValue() == 1) {
                                    //判断页面是否设置提前报警时间
                                    Integer productExpiredTime = Tools.getInteger(alarmRule.getProductExpiredTime());
                                    int alarmTime = now + productExpiredTime.intValue() * 24 * 3600;
                                    if (Tools.getInteger(deviceAuth.getExpireTime()).intValue() <= alarmTime) {
                                        //判断当天生效时间范围
                                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                                        String day = sdf.format(new Date());
                                        //有效开始时间
                                        String startTimeStr = day + " " + alarmRule.getStartTime() + ":00";
                                        int startTime = DateUtil.getStrTime(startTimeStr);
                                        //有效结束
                                        String endTimeStr = day + " " + alarmRule.getEndTime() + ":00";
                                        int endTime = DateUtil.getStrTime(endTimeStr);
                                        //验收当前时间是否在有效时间之内，在之内才触发报警消息
                                        if (now >= startTime && now <= endTime) {
                                            //重要提醒：机器人：${devicename}(${deviceid})的${module}功能即将过期，来自运营商${phone}
                                            AlarmMsgFeignDto alarmMsgFeignDto = new AlarmMsgFeignDto();
                                            alarmMsgFeignDto.setMerId(deviceWechatInfo.getMerId());
                                            alarmMsgFeignDto.setType(SysMsgTypeEnum.PRO_AUTH_EXPIRED.getValue()); //机器人功能到期
                                            alarmMsgFeignDto.setDeviceUniqueId(deviceWechatInfo.getId());
                                            alarmMsgFeignDto.setDeviceType(DeviceTypeEnum.DT_PC_WECHAT.getKey());
                                            //消息
                                            JSONObject ext = new JSONObject();
                                            ext.put("deviceid", deviceAuth.getDeviceId());
                                            String devicename = Tools.getStr(deviceWechatInfo.getDeviceName());
                                            //如果备注不为空，则加上（机器人备注）
                                            if (StringUtils.isNotBlank(deviceWechatInfo.getDeviceRemark())) {
                                                devicename = devicename + "(" + Tools.getStr(deviceWechatInfo.getDeviceRemark()) + ")";
                                            }
                                            ext.put("devicename", devicename);
                                            DeviceProductKeyEnum deviceProductKeyEnum = DeviceProductKeyEnum.getValue(deviceAuth.getProductCode());
                                            if (deviceProductKeyEnum != null) {
                                                ext.put("module", deviceProductKeyEnum.getDesc());
                                            } else {
                                                ext.put("module", "");
                                            }
                                            alarmMsgFeignDto.setExt(ext.toJSONString());
//                                            UzaiRespVo uzaiRespVo = uzaiBroadcastFeignService.sysMsgPush(alarmMsgFeignDto);
//                                            logger.info("---个人微信机器人授权功能到期报警消息-para={}, result={}", JSONObject.toJSONString(alarmMsgFeignDto), JSONObject.toJSONString(uzaiRespVo));
                                            //2024-01-09修改成直接发送MQ
                                            noticeMsgPushProducerService.sendSysAlarmMsgAsync(alarmMsgFeignDto);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                deviceAuthQuery_expired.setIdStart(idStart);
                deviceAuthList_expired = deviceAuthMapper.findByList(page, deviceAuthQuery_expired);
            }
        } catch (Exception e) {
            logger.info(e.getMessage());
        } finally {
            //删除限流key
            redisTemplate.delete(taskLimitKet);
        }
    }

    /**
     * 企业微信机器人授权功能到期发送报警消息
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void deviceWxworkExpiredAlarmMsg() {

        //限流key
        String taskLimitKet = "-deviceWechatOffLineAlarmMsg-taskLimitKey-";
        Object object = redisTemplate.opsForValue().get(taskLimitKet);
        if (object != null) {
            return;
        }
        //保存限流key
        redisTemplate.opsForValue().set(taskLimitKet, taskLimitKet, 30, TimeUnit.MINUTES);

        logger.info("-----调用企业机器人授权功能到期发送报警消息线程----");

        try {
            int now = DateUtil.getNowTime();
            //已经到期
            DeviceAuthQuery deviceAuthQuery_expired = new DeviceAuthQuery();
            deviceAuthQuery_expired.setDeviceType(DeviceTypeEnum.DT_WORK_WECHAT.getKey());
            //只搜索到期15天之内的授权
            //int expireTimeStart = now - 15 * 24 * 3600;
            //只搜索未到期的授权
            int expireTimeStart = now;
            deviceAuthQuery_expired.setExpireTimeStart(expireTimeStart);
            //将要到期7天之内的授权
            int queryEndTime = now + 7 * 24 * 3600;
            deviceAuthQuery_expired.setExpireTimeEnd(queryEndTime);

            //查询机器人已经到期
            Page<DeviceAuth> page = new Page<>();
            page.setCurrent(1);//只查第一页
            page.setSize(10); //每页查询10个
            page.addOrder(OrderItem.asc("id"));//默认id升序
            Long idStart = 0L;

            List<DeviceAuth> deviceAuthList_expired = deviceAuthMapper.findByList(page, deviceAuthQuery_expired);
            while (deviceAuthList_expired != null && deviceAuthList_expired.size() > 0) {
                for (DeviceAuth deviceAuth : deviceAuthList_expired) {

                    if (deviceAuth.getId().longValue() > idStart.longValue()) {
                        idStart = deviceAuth.getId();
                    }
                    //未到期和即将7天到期之内的授权才处理
                    if (deviceAuth.getExpireTime().intValue() >= expireTimeStart && deviceAuth.getExpireTime().intValue() <= queryEndTime) {

                        //限流判断(30秒内判断一次)
                        boolean inRateLimit = ratelimitService.inRateLimit("deviceWxworkExpiredAlarmMsg-" + deviceAuth.getId(), 1, 30);
                        if (!inRateLimit) {
                            //logger.info("---inRateLimit false. deviceUniqueId={}", deviceAuth.getDeviceUniqueId());
                            continue;
                        }
                        DeviceWxworkInfo deviceWxworkInfo = deviceWxworkInfoMapper.selectByDeviceId(deviceAuth.getDeviceId());
                        if (deviceWxworkInfo != null && deviceWxworkInfo.getAlarmRuleId() != null) {
                            AlarmRule alarmRule = alarmRuleMapper.selectById(deviceWxworkInfo.getAlarmRuleId(), deviceWxworkInfo.getMerId());
                            if (alarmRule != null && Tools.getInteger(alarmRule.getStatus()).intValue() == 1) { //报警规则开启才判断
                                //是否产品到期报警
                                if (Tools.getInteger(alarmRule.getProductExpired()).intValue() == 1) {

                                    //判断页面是否设置提前报警时间
                                    Integer productExpiredTime = Tools.getInteger(alarmRule.getProductExpiredTime());
                                    int alarmTime = now + productExpiredTime.intValue() * 24 * 3600;
                                    if (Tools.getInteger(deviceAuth.getExpireTime()).intValue() <= alarmTime) {
                                        //判断当天生效时间范围
                                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                                        String day = sdf.format(new Date());
                                        //有效开始时间
                                        String startTimeStr = day + " " + alarmRule.getStartTime() + ":00";
                                        int startTime = DateUtil.getStrTime(startTimeStr);
                                        //有效结束
                                        String endTimeStr = day + " " + alarmRule.getEndTime() + ":00";
                                        int endTime = DateUtil.getStrTime(endTimeStr);
                                        //验收当前时间是否在有效时间之内，在之内才触发报警消息
                                        if (now >= startTime && now <= endTime) {
                                            //重要提醒：机器人：${devicename}(${deviceid})的${module}功能即将过期，来自运营商${phone}
                                            AlarmMsgFeignDto alarmMsgFeignDto = new AlarmMsgFeignDto();
                                            alarmMsgFeignDto.setMerId(deviceWxworkInfo.getMerId());
                                            alarmMsgFeignDto.setType(SysMsgTypeEnum.PRO_AUTH_EXPIRED.getValue()); //机器人功能到期
                                            alarmMsgFeignDto.setDeviceUniqueId(deviceWxworkInfo.getId());
                                            alarmMsgFeignDto.setDeviceType(DeviceTypeEnum.DT_WORK_WECHAT.getKey());
                                            //消息
                                            JSONObject ext = new JSONObject();
                                            ext.put("deviceid", deviceAuth.getDeviceId());
                                            String devicename = Tools.getStr(deviceWxworkInfo.getDeviceName());
                                            //如果备注不为空，则加上（机器人备注）
                                            if (StringUtils.isNotBlank(deviceWxworkInfo.getDeviceRemark())) {
                                                devicename = devicename + "(" + Tools.getStr(deviceWxworkInfo.getDeviceRemark()) + ")";
                                            }
                                            ext.put("devicename", devicename);
                                            DeviceProductKeyEnum deviceProductKeyEnum = DeviceProductKeyEnum.getValue(deviceAuth.getProductCode());
                                            if (deviceProductKeyEnum != null) {
                                                ext.put("module", deviceProductKeyEnum.getDesc());
                                            } else {
                                                ext.put("module", "");
                                            }
                                            alarmMsgFeignDto.setExt(ext.toJSONString());
//                                            UzaiRespVo uzaiRespVo = uzaiBroadcastFeignService.sysMsgPush(alarmMsgFeignDto);
//                                            logger.info("---企业微信机器人授权功能到期报警消息-para={}, result={}", JSONObject.toJSONString(alarmMsgFeignDto), JSONObject.toJSONString(uzaiRespVo));

                                            //2024-01-09修改成直接发送MQ
                                            noticeMsgPushProducerService.sendSysAlarmMsgAsync(alarmMsgFeignDto);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                deviceAuthQuery_expired.setIdStart(idStart);
                deviceAuthList_expired = deviceAuthMapper.findByList(page, deviceAuthQuery_expired);
            }
        } catch (Exception e) {
            logger.info(e.getMessage());
        } finally {
            //删除限流key
            redisTemplate.delete(taskLimitKet);
        }

    }

    /**
     * 淘宝联盟授权功能到期发送报警消息
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void tbTokenExpiredAlarmMsg() {
        //限流key
        String taskLimitKet = "-tbTokenExpiredAlarmMsg-taskLimitKey-";
        Object object = redisTemplate.opsForValue().get(taskLimitKet);
        if (object != null) {
            return;
        }
        //保存限流key
        redisTemplate.opsForValue().set(taskLimitKet, taskLimitKet, 30, TimeUnit.MINUTES);

        logger.info("-----调用淘宝联盟到期发送报警消息线程----");

        try {
            int now = DateUtil.getNowTime();
            //已经到期
            TbTokenQuery tbTokenQuery_expired = new TbTokenQuery();
            //只搜索到期15天之内的授权
            //int expireTimeStart = now - 15 * 24 * 3600;
            //只搜索未到期的授权
            int expireTimeStart = now;
            tbTokenQuery_expired.setExpireTimeStart(expireTimeStart);
            //将要到期7天之内的授权
            int queryEndTime = now + 7 * 24 * 3600;
            tbTokenQuery_expired.setExpireTimeEnd(queryEndTime);
            //只查询淘宝联盟（饿了么联盟已经下架）
            tbTokenQuery_expired.setType(0); //

            //查询机器人已经到期
            Page<TbToken> page = new Page<>();
            page.setCurrent(1);//只查第一页
            page.setSize(10); //每页查询10个
            page.addOrder(OrderItem.asc("id"));//默认id升序
            Long idStart = 0L;

            List<TbToken> tbTokenList_expired = tbTokenMapper.findByList(page, tbTokenQuery_expired);
            while (tbTokenList_expired != null && tbTokenList_expired.size() > 0) {
                for (TbToken tbToken : tbTokenList_expired) {
                    if (tbToken.getId().longValue() > idStart.longValue()) {
                        idStart = tbToken.getId();
                    }
                    //限流判断(30秒内判断一次)
                    boolean inRateLimit = ratelimitService.inRateLimit("tbTokenExpiredAlarmMsg-" + tbToken.getId(), 1, 30);
                    if (!inRateLimit) {
                        //logger.info("---inRateLimit false. deviceUniqueId={}", deviceAuth.getDeviceUniqueId());
                        continue;
                    }

                    //从缓存种获取事件报警监控
                    MerBaseConfig merBaseConfig = merBaseConfigMapper.selectByMerId(tbToken.getMerId(), MerConfigKeyEnum.ALARM_EVENT_CONFIG.getValue());
                    if (merBaseConfig != null && StringUtils.isNotBlank(merBaseConfig.getVal())) {
                        AlarmEventConfigVo alarmEventConfigVo = JSONObject.parseObject(merBaseConfig.getVal(), AlarmEventConfigVo.class);
                        //判断淘宝联盟到期报警开关是否开启
                        if (alarmEventConfigVo != null && Tools.getInteger(alarmEventConfigVo.getTbTokenExpired()).intValue() == 1) {
                            //淘宝报警提前时间
                            Integer tbTokenExpired = Tools.getInteger(alarmEventConfigVo.getTbTokenExpiredTime());
                            int alarmTime = now + tbTokenExpired.intValue() * 24 * 3600;
                            //淘宝联盟到期时间
                            int tbTokenExpiredTime = Tools.getInteger(tbToken.getExptime()).intValue();
                            if (tbTokenExpiredTime <= alarmTime) {
                                //重要提醒：机器人：${devicename}(${deviceid})的${module}功能即将过期，来自运营商${phone}
                                AlarmMsgFeignDto alarmMsgFeignDto = new AlarmMsgFeignDto();
                                alarmMsgFeignDto.setMerId(tbToken.getMerId());
                                alarmMsgFeignDto.setType(SysMsgTypeEnum.TB_TOKEN_EXPIRED.getValue()); //淘宝联盟到期
                                //消息
                                JSONObject ext = new JSONObject();
                                ext.put("user", tbToken.getUserName());
                                ext.put("time", DateFormatUtil.timeToDateStr(tbTokenExpiredTime));
                                ext.put("content", "");
                                ext.put("platform", ProductKeyEnum.TB.getDesc());
                                alarmMsgFeignDto.setExt(ext.toJSONString());
//                                UzaiRespVo uzaiRespVo = uzaiBroadcastFeignService.sysMsgPush(alarmMsgFeignDto);
//                                logger.info("---淘宝联盟到期报警消息-para={}, result={}", JSONObject.toJSONString(alarmMsgFeignDto), JSONObject.toJSONString(uzaiRespVo));

                                //2024-01-09修改成直接发送MQ
                                noticeMsgPushProducerService.sendSysAlarmMsgAsync(alarmMsgFeignDto);
                            }
                        }
                    }
                }
                tbTokenQuery_expired.setIdStart(idStart);
                tbTokenList_expired = tbTokenMapper.findByList(page, tbTokenQuery_expired);
            }
        } catch (Exception e) {
            logger.info(e.getMessage());
        } finally {
            //删除限流key
            redisTemplate.delete(taskLimitKet);
        }

    }

    /**
     * 抖客联盟授权功能到期发送报警消息
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void dyTokenExpiredAlarmMsg() {

        //限流key
        String taskLimitKet = "-dyTokenExpiredAlarmMsg-taskLimitKey-";
        Object object = redisTemplate.opsForValue().get(taskLimitKet);
        if (object != null) {
            return;
        }
        //保存限流key
        redisTemplate.opsForValue().set(taskLimitKet, taskLimitKet, 30, TimeUnit.MINUTES);

        logger.info("-----调用抖客联盟到期发送报警消息线程----");

        try {
            int now = DateUtil.getNowTime();
            //已经到期
            DyTokenQuery dyTokenQuery_expired = new DyTokenQuery();
            //抖音抖客联盟
            dyTokenQuery_expired.setType(1);
            dyTokenQuery_expired.setTokenType(0);
            //只搜索到期15天之内的授权
            //int expireTimeStart = now - 15 * 24 * 3600;
            //只搜索未到期的授权
            int expireTimeStart = now;
            dyTokenQuery_expired.setExpireTimeStart(expireTimeStart);
            //将要到期7天之内的授权
            int queryEndTime = now + 7 * 24 * 3600;
            dyTokenQuery_expired.setExpireTimeEnd(queryEndTime);

            //查询机器人已经到期
            Page<DyToken> page = new Page<>();
            page.setCurrent(1);//只查第一页
            page.setSize(10); //每页查询10个
            page.addOrder(OrderItem.asc("id"));//默认id升序
            Long idStart = 0L;

            List<DyToken> dyTokenList_expired = dyTokenMapper.findByList(page, dyTokenQuery_expired);
            while (dyTokenList_expired != null && dyTokenList_expired.size() > 0) {
                for (DyToken dyToken : dyTokenList_expired) {
                    if (dyToken.getId().longValue() > idStart.longValue()) {
                        idStart = dyToken.getId();
                    }
                    //限流判断(30秒内判断一次)
                    boolean inRateLimit = ratelimitService.inRateLimit("dyTokenExpiredAlarmMsg-" + dyToken.getId(), 1, 30);
                    if (!inRateLimit) {
                        //logger.info("---inRateLimit false. deviceUniqueId={}", deviceAuth.getDeviceUniqueId());
                        continue;
                    }

                    //从缓存种获取事件报警监控
                    MerBaseConfig merBaseConfig = merBaseConfigMapper.selectByMerId(dyToken.getMerId(), MerConfigKeyEnum.ALARM_EVENT_CONFIG.getValue());
                    if (merBaseConfig != null && StringUtils.isNotBlank(merBaseConfig.getVal())) {
                        AlarmEventConfigVo alarmEventConfigVo = JSONObject.parseObject(merBaseConfig.getVal(), AlarmEventConfigVo.class);
                        //判断抖客联盟到期报警开关是否开启
                        if (alarmEventConfigVo != null && Tools.getInteger(alarmEventConfigVo.getDyTokenExpired()).intValue() == 1) {
                            //抖客报警提前时间
                            Integer dyTokenExpired = Tools.getInteger(alarmEventConfigVo.getDyTokenExpiredTime());
                            int alarmTime = now + dyTokenExpired.intValue() * 24 * 3600;
                            //抖客联盟到期时间
                            int tbTokenExpiredTime = Tools.getInteger(dyToken.getExptime()).intValue();
                            if (tbTokenExpiredTime <= alarmTime) {
                                //重要提醒：机器人：${devicename}(${deviceid})的${module}功能即将过期，来自运营商${phone}
                                AlarmMsgFeignDto alarmMsgFeignDto = new AlarmMsgFeignDto();
                                alarmMsgFeignDto.setMerId(dyToken.getMerId());
                                alarmMsgFeignDto.setType(SysMsgTypeEnum.DY_TOKEN_EXPIRED.getValue()); //采用淘宝联盟到期报警短信模板
                                //消息
                                JSONObject ext = new JSONObject();
                                ext.put("user", dyToken.getName());
                                ext.put("time", DateFormatUtil.timeToDateStr(tbTokenExpiredTime));
                                ext.put("content", "");
                                ext.put("platform", ProductKeyEnum.DY.getDesc());
                                alarmMsgFeignDto.setExt(ext.toJSONString());
//                                UzaiRespVo uzaiRespVo = uzaiBroadcastFeignService.sysMsgPush(alarmMsgFeignDto);
//                                logger.info("---抖客联盟到期报警消息-para={}, result={}", JSONObject.toJSONString(alarmMsgFeignDto), JSONObject.toJSONString(uzaiRespVo));
                                //2024-01-09修改成直接发送MQ
                                noticeMsgPushProducerService.sendSysAlarmMsgAsync(alarmMsgFeignDto);
                            }
                        }
                    }
                }
                dyTokenQuery_expired.setIdStart(idStart);
                dyTokenList_expired = dyTokenMapper.findByList(page, dyTokenQuery_expired);
            }
        } catch (Exception e) {
            logger.info(e.getMessage());
        } finally {
            //删除限流key
            redisTemplate.delete(taskLimitKet);
        }
    }

    /**
     * 拼多多授权功能到期发送报警消息
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void pddTokenExpiredAlarmMsg() {

        //限流key
        String taskLimitKet = "-pddTokenExpiredAlarmMsg-taskLimitKey-";
        Object object = redisTemplate.opsForValue().get(taskLimitKet);
        if (object != null) {
            return;
        }
        //保存限流key
        redisTemplate.opsForValue().set(taskLimitKet, taskLimitKet, 30, TimeUnit.MINUTES);

        logger.info("-----调用拼多多联盟到期发送报警消息线程----");
        try {
            int now = DateUtil.getNowTime();
            //已经到期
            PddTokenQuery pddTokenQuery_expired = new PddTokenQuery();
            //只搜索到期15天之内的授权
            //int expireTimeStart = now - 15 * 24 * 3600;
            //只搜索未到期的授权
            int expireTimeStart = now;
            pddTokenQuery_expired.setExpireTimeStart(expireTimeStart);
            //将要到期7天之内的授权
            int queryEndTime = now + 7 * 24 * 3600;
            pddTokenQuery_expired.setExpireTimeEnd(queryEndTime);

            //查询机器人已经到期
            Page<PddToken> page = new Page<>();
            page.setCurrent(1);//只查第一页
            page.setSize(10); //每页查询10个
            page.addOrder(OrderItem.asc("id"));//默认id升序
            Long idStart = 0L;

            List<PddToken> pddTokenList_expired = pddTokenMapper.findByList(page, pddTokenQuery_expired);
            while (pddTokenList_expired != null && pddTokenList_expired.size() > 0) {
                for (PddToken pddToken : pddTokenList_expired) {
                    if (pddToken.getId().longValue() > idStart.longValue()) {
                        idStart = pddToken.getId();
                    }
                    //限流判断(30秒内判断一次)
                    boolean inRateLimit = ratelimitService.inRateLimit("pddTokenExpiredAlarmMsg-" + pddToken.getId(), 1, 30);
                    if (!inRateLimit) {
                        //logger.info("---inRateLimit false. deviceUniqueId={}", deviceAuth.getDeviceUniqueId());
                        continue;
                    }

                    //从缓存种获取事件报警监控
                    MerBaseConfig merBaseConfig = merBaseConfigMapper.selectByMerId(pddToken.getMerId(), MerConfigKeyEnum.ALARM_EVENT_CONFIG.getValue());
                    if (merBaseConfig != null && StringUtils.isNotBlank(merBaseConfig.getVal())) {
                        AlarmEventConfigVo alarmEventConfigVo = JSONObject.parseObject(merBaseConfig.getVal(), AlarmEventConfigVo.class);
                        //判断拼多多联盟到期报警开关是否开启
                        if (alarmEventConfigVo != null && Tools.getInteger(alarmEventConfigVo.getPddTokenExpired()).intValue() == 1) {
                            //拼多多报警提前时间
                            Integer pddTokenExpired = Tools.getInteger(alarmEventConfigVo.getPddTokenExpiredTime());
                            int alarmTime = now + pddTokenExpired.intValue() * 24 * 3600;
                            //拼多多联盟到期时间
                            int pddTokenExpiredTime = Tools.getInteger(pddToken.getExpiresin()).intValue() + Tools.getInteger(pddToken.getAuthTime()).intValue();
                            if (pddTokenExpiredTime <= alarmTime) {
                                //重要提醒：机器人：${devicename}(${deviceid})的${module}功能即将过期，来自运营商${phone}
                                AlarmMsgFeignDto alarmMsgFeignDto = new AlarmMsgFeignDto();
                                alarmMsgFeignDto.setMerId(pddToken.getMerId());
                                alarmMsgFeignDto.setType(SysMsgTypeEnum.PDD_TOKEN_EXPIRED.getValue()); //拼多多联盟到期
                                //消息
                                JSONObject ext = new JSONObject();
                                ext.put("user", pddToken.getUserId());
                                ext.put("time", DateFormatUtil.timeToDateStr(pddTokenExpiredTime));
                                ext.put("content", "");
                                ext.put("platform", ProductKeyEnum.PDD.getDesc());
                                alarmMsgFeignDto.setExt(ext.toJSONString());
//                                UzaiRespVo uzaiRespVo = uzaiBroadcastFeignService.sysMsgPush(alarmMsgFeignDto);
//                                logger.info("---拼多多联盟到期报警消息-para={}, result={}", JSONObject.toJSONString(alarmMsgFeignDto), JSONObject.toJSONString(uzaiRespVo));
                                //2024-01-09修改成直接发送MQ
                                noticeMsgPushProducerService.sendSysAlarmMsgAsync(alarmMsgFeignDto);
                            }
                        }
                    }
                }
                pddTokenQuery_expired.setIdStart(idStart);
                pddTokenList_expired = pddTokenMapper.findByList(page, pddTokenQuery_expired);
            }
        } catch (Exception e) {
            logger.info(e.getMessage());
        } finally {
            //删除限流key
            redisTemplate.delete(taskLimitKet);
        }
    }

    /**
     * 唯品会授权功能到期发送报警消息
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void vphTokenExpiredAlarmMsg() {
        //限流key
        String taskLimitKet = "-vphTokenExpiredAlarmMsg-taskLimitKey-";
        Object object = redisTemplate.opsForValue().get(taskLimitKet);
        if (object != null) {
            return;
        }
        //保存限流key
        redisTemplate.opsForValue().set(taskLimitKet, taskLimitKet, 30, TimeUnit.MINUTES);

        logger.info("-----调用唯品会联盟到期发送报警消息线程----");

        try {
            int now = DateUtil.getNowTime();
            //已经到期
            VphTokenQuery vphTokenQuery_expired = new VphTokenQuery();
            //只搜索到期15天之内的授权
            //int expireTimeStart = now - 15 * 24 * 3600;
            //只搜索未到期的授权
            int expireTimeStart = now;
            vphTokenQuery_expired.setExpireTimeStart(expireTimeStart);
            //将要到期7天之内的授权
            int queryEndTime = now + 7 * 24 * 3600;
            vphTokenQuery_expired.setExpireTimeEnd(queryEndTime);

            //查询机器人已经到期
            Page<VphToken> page = new Page<>();
            page.setCurrent(1);//只查第一页
            page.setSize(10); //每页查询10个
            page.addOrder(OrderItem.asc("id"));//默认id升序
            Long idStart = 0L;

            List<VphToken> vphTokenList_expired = vphTokenMapper.findByList(page, vphTokenQuery_expired);
            while (vphTokenList_expired != null && vphTokenList_expired.size() > 0) {
                for (VphToken vphToken : vphTokenList_expired) {
                    if (vphToken.getId().longValue() > idStart.longValue()) {
                        idStart = vphToken.getId();
                    }
                    //限流判断(30秒内判断一次)
                    boolean inRateLimit = ratelimitService.inRateLimit("vphTokenExpiredAlarmMsg-" + vphToken.getId(), 1, 30);
                    if (!inRateLimit) {
                        //logger.info("---inRateLimit false. deviceUniqueId={}", deviceAuth.getDeviceUniqueId());
                        continue;
                    }

                    //从缓存种获取事件报警监控
                    MerBaseConfig merBaseConfig = merBaseConfigMapper.selectByMerId(vphToken.getMerId(), MerConfigKeyEnum.ALARM_EVENT_CONFIG.getValue());
                    if (merBaseConfig != null && StringUtils.isNotBlank(merBaseConfig.getVal())) {
                        AlarmEventConfigVo alarmEventConfigVo = JSONObject.parseObject(merBaseConfig.getVal(), AlarmEventConfigVo.class);
                        //判断唯品会联盟到期报警开关是否开启
                        if (alarmEventConfigVo != null && Tools.getInteger(alarmEventConfigVo.getVphTokenExpired()).intValue() == 1) {
                            //唯品会报警提前时间
                            Integer vphTokenExpired = Tools.getInteger(alarmEventConfigVo.getVphTokenExpiredTime());
                            int alarmTime = now + vphTokenExpired.intValue() * 24 * 3600;
                            //唯品会联盟到期时间
                            int vphTokenExpiredTime = Tools.getInteger(vphToken.getExpiresTime()).intValue();
                            if (vphTokenExpiredTime <= alarmTime) {
                                //重要提醒：机器人：${devicename}(${deviceid})的${module}功能即将过期，来自运营商${phone}
                                AlarmMsgFeignDto alarmMsgFeignDto = new AlarmMsgFeignDto();
                                alarmMsgFeignDto.setMerId(vphToken.getMerId());
                                alarmMsgFeignDto.setType(SysMsgTypeEnum.VPH_TOKEN_EXPIRED.getValue()); //唯品会联盟到期
                                //消息
                                JSONObject ext = new JSONObject();
                                ext.put("user", vphToken.getOpenId());
                                ext.put("time", DateFormatUtil.timeToDateStr(vphTokenExpiredTime));
                                ext.put("content", "");
                                ext.put("platform", ProductKeyEnum.VPH.getDesc());
                                alarmMsgFeignDto.setExt(ext.toJSONString());
//                                UzaiRespVo uzaiRespVo = uzaiBroadcastFeignService.sysMsgPush(alarmMsgFeignDto);
//                                logger.info("---唯品会联盟到期报警消息-para={}, result={}", JSONObject.toJSONString(alarmMsgFeignDto), JSONObject.toJSONString(uzaiRespVo));

                                //2024-01-09修改成直接发送MQ
                                noticeMsgPushProducerService.sendSysAlarmMsgAsync(alarmMsgFeignDto);
                            }
                        }
                    }
                }
                vphTokenQuery_expired.setIdStart(idStart);
                vphTokenList_expired = vphTokenMapper.findByList(page, vphTokenQuery_expired);
            }
        } catch (Exception e) {
            logger.info(e.getMessage());
        } finally {
            //删除限流key
            redisTemplate.delete(taskLimitKet);
        }
    }

    /**
     * 自动发送朋友圈
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void autoSendPyqSync() {

        //限流key
        String taskLimitKet = "-autoSendPyqSync-taskLimitKey-";
        Object object = redisTemplate.opsForValue().get(taskLimitKet);
        if (object != null) {
            return;
        }
        //保存限流key
        redisTemplate.opsForValue().set(taskLimitKet, taskLimitKet, 30, TimeUnit.MINUTES);

        logger.info("-----调用自动发送朋友圈任务--xxlJob start--");

        try {
            //查询当前所有开启的自动发圈的配置方案
            int now = DateUtil.getNowTime();

            // 获取当前时间
            LocalDateTime now_localDateTime = LocalDateTime.now();

            String yyyyMMdd = Tools.getDateFormat(new Date(), "yyyy-MM-dd");

            PyqAutoConfigQuery pyqAutoConfigQuery = new PyqAutoConfigQuery();
            pyqAutoConfigQuery.setStatus(1); //启动

            //查询所有的自动发圈配置记录
            Page<PyqAutoConfig> page = new Page<>();
            page.setCurrent(1);//只查第一页
            page.setSize(10); //每页查询10个
            page.addOrder(OrderItem.asc("id"));//默认id升序
            Long idStart = 0L;
            List<PyqAutoConfig> pyqAutoConfigList = pyqAutoConfigMapper.findByList(page, pyqAutoConfigQuery);
            while (pyqAutoConfigList != null && pyqAutoConfigList.size() > 0) {
                for (PyqAutoConfig pyqAutoConfig : pyqAutoConfigList) {
                    try {
                        if (pyqAutoConfig.getId().longValue() > idStart.longValue()) {
                            idStart = pyqAutoConfig.getId();
                        }

                        //限流判断
                        String rateLimitKey = "autoSendPyq-configId=" + pyqAutoConfig.getId();
                        boolean inRateLimit = ratelimitService.inRateLimit(rateLimitKey, 1, 300);
                        if (!inRateLimit) {
                            //logger.info("--inRateLimit false. tradeno={}",alipayDetail.getTradeno());
                            continue;
                        }

                        //开始限制时间（HH:mm）
                        String limitTimeStart = pyqAutoConfig.getLimitTimeStart();
                        if (StringUtils.isBlank(limitTimeStart)) {
                            limitTimeStart = "00:00";
                        }

                        //结束限制时间（HH:mm）
                        String limitTimeEnd = pyqAutoConfig.getLimitTimeEnd();
                        if (StringUtils.isBlank(limitTimeEnd)) {
                            limitTimeEnd = "23:59";
                        }

                        //判断当前时间是否在自动任务开启时间区间内
                        boolean withinTimeInterval = Tools.isWithinTimeInterval(now_localDateTime, LocalTime.parse(limitTimeStart), LocalTime.parse(limitTimeEnd));
                        //不在区间内，则跳过
                        if (!withinTimeInterval) {
                            continue;
                        }

                        //发送间隔最小时间
                        Integer rateMin = Tools.getInteger(pyqAutoConfig.getRateMin());
                        //发送间隔最大时间
                        Integer rateMax = Tools.getInteger(pyqAutoConfig.getRateMax());
                        //上次发送时间
                        Integer sendTime = Tools.getInteger(pyqAutoConfig.getSendTime());
                        //这次发送时间,默认等于当前时间
                        int sendTimeNew = now;
                        if (sendTime.intValue() != 0) { //已经开始发送配置方案
                            if (sendTime.intValue() + rateMin.intValue() * 60 > now) {//上次发送时间+最小时间间隔，如果还大于当前时间，表示还未轮到，
                                continue;
                            }

                            //判断旧发送时间是否在允许区间内
                            Instant instant_sendTime = Instant.ofEpochMilli(sendTime * 1000L);
                            LocalDateTime localDateTime_sendTime = LocalDateTime.ofInstant(instant_sendTime, ZoneId.systemDefault());
                            boolean withinTimeInterval_sendTime = Tools.isWithinTimeInterval(localDateTime_sendTime, LocalTime.parse(limitTimeStart), LocalTime.parse(limitTimeEnd));
                            //不在区间内，则新发送时间为当前时间
                            if (!withinTimeInterval_sendTime) {
                                sendTimeNew = now;
                            } else {
                                //旧发送时间在允许区间内，需要判断上次发送是否在当天，如果是当天表示已经发送过一次，需要判断是否只发送一次,如果是，则跳过不发送
                                //判断当前时间跟上次处理僵尸粉时间是否是同一天
                                if (DateUtil.isSameDay(new Date(sendTime * 1000L), new Date())) {//是同一天，则需要判断是否只发送一次
                                    if (Tools.getInteger(pyqAutoConfig.getSendCycle()).intValue() == 1) {
                                        continue;
                                    }
                                }

                                //获取最小和最大时间的随机数（分数）
                                int random = (int) (Math.random() * (rateMax - rateMin + 1) + rateMin);
                                sendTimeNew = sendTime + random * 60;
                            }
                        } else { //如果等于空，则表示第一次发送，默认为0
                            sendTimeNew = now;
                        }

                        //如果发送时间小于当前时间，则默认按照当前时间来发
                        if (sendTimeNew < now) {
                            sendTimeNew = now;
                        }

                        //判断新发送时间是否在允许区间内，不在则跳过
                        Instant instant_sendTimeNew = Instant.ofEpochMilli(sendTimeNew * 1000L);
                        LocalDateTime localDateTime_sendTimeNew = LocalDateTime.ofInstant(instant_sendTimeNew, ZoneId.systemDefault());
                        boolean withinTimeInterval_sendTimeNew = Tools.isWithinTimeInterval(localDateTime_sendTimeNew, LocalTime.parse(limitTimeStart), LocalTime.parse(limitTimeEnd));
                        //不在区间内，则跳过
                        if (!withinTimeInterval_sendTimeNew) {
                            continue;
                        }

                        //更新新的发送时间
                        pyqAutoConfig.setSendTime(sendTimeNew);

                        //自动发送朋友圈
                        pyqAutoSendService.autoSendPyq(pyqAutoConfig);

                        //保存成功之后，手动删除限流redisKey
                        redisTemplate.delete(rateLimitKey);
                    } catch (Exception e) {
                        logger.error("--自动发圈失败--error={}", e.getMessage());
                    }
                }

                pyqAutoConfigQuery.setIdStart(idStart);
                pyqAutoConfigList = pyqAutoConfigMapper.findByList(page, pyqAutoConfigQuery);

            }
        } catch (Exception e) {
            logger.info(e.getMessage());
        } finally {
            //删除限流key
            redisTemplate.delete(taskLimitKet);
        }

    }

    /**
     * 自动发送朋友圈评论
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void autoSendPyqCommentSync() {
        //限流key
        String taskLimitKet = "-autoSendPyqCommentSync-taskLimitKey-";
        Object object = redisTemplate.opsForValue().get(taskLimitKet);
        if (object != null) {
            return;
        }
        //保存限流key
        redisTemplate.opsForValue().set(taskLimitKet, taskLimitKet, 30, TimeUnit.MINUTES);


        logger.info("-----调用自动跟发朋友圈-发送朋友圈评论任务--xxlJob start--");

        try {
            //查询当前所有朋友圈评论列表
            PyqFollowCommentQuery pyqFollowCommentQuery = new PyqFollowCommentQuery();
            pyqFollowCommentQuery.setStatus(0); //未发送

            //查询所有的pyq评论记录
            Page<PyqFollowComment> page = new Page<>();
            page.setCurrent(1);//只查第一页
            page.setSize(10); //每页查询10个
            page.addOrder(OrderItem.asc("id"));//默认id升序
            Long idStart = 0L;
            List<PyqFollowComment> pyqFollowCommentList = pyqFollowCommentMapper.findByList(page, pyqFollowCommentQuery);
            while (pyqFollowCommentList != null && pyqFollowCommentList.size() > 0) {
                for (PyqFollowComment pyqFollowComment : pyqFollowCommentList) {
                    try {
                        if (pyqFollowComment.getId().longValue() > idStart.longValue()) {
                            idStart = pyqFollowComment.getId();
                        }

                        //限流判断
                        String rateLimitKey = "autoSendPyqComment-pyqCommentId=" + pyqFollowComment.getId();
                        boolean inRateLimit = ratelimitService.inRateLimit(rateLimitKey, 1, 30);
                        if (!inRateLimit) {
                            //logger.info("--inRateLimit false. tradeno={}",alipayDetail.getTradeno());
                            continue;
                        }

                        //自动发送朋友圈评论
                        pyqAutoSendService.autoSendPyqComment(pyqFollowComment);

                        //保存成功之后，手动删除限流redisKey
                        redisTemplate.delete(rateLimitKey);
                    } catch (Exception e) {
                        logger.error("--自动发圈失败--error={}", e.getMessage());
                    }
                }

                pyqFollowCommentQuery.setIdStart(idStart);
                pyqFollowCommentList = pyqFollowCommentMapper.findByList(page, pyqFollowCommentQuery);
                ;
            }
        } catch (Exception e) {
            logger.info(e.getMessage());
        } finally {
            //删除限流key
            redisTemplate.delete(taskLimitKet);
        }

    }

    /**
     * 自动删除历史朋友圈信息
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void deletePyqJobHistorySync() {
        logger.info("-----调用自动删除历史朋友圈任务--xxlJob start--");

        //查询当前所有开启的自动发圈的配置方案
        int now = DateUtil.getNowTime();
        //查询历史时间
        int queryEndTime = now - 10 * 24 * 3600;

        PyqJobQuery pyqJobQuery = new PyqJobQuery();
        pyqJobQuery.setQueryEndTime(queryEndTime); //查询结束时间
        //查询所有的自动发圈配置记录
        Page<PyqJob> page = new Page<>();
        page.setCurrent(1);//只查第一页
        page.setSize(10); //每页查询10个
        page.addOrder(OrderItem.asc("id"));//默认id升序
        Long idStart = 0L;
        List<PyqJob> pyqJobList = pyqJobMapper.findByList(page, pyqJobQuery);
        while (pyqJobList != null && pyqJobList.size() > 0) {

            //晚上23:30:00之后，跳出线程
            if (Tools.timeCompare("23:30:00")) {
                break;
            }

            for (PyqJob pyqJob : pyqJobList) {
                //限流判断
                String rateLimitKey = "deletePyqJobHistorySync-pyqId=" + pyqJob.getId();
                boolean inRateLimit = ratelimitService.inRateLimit(rateLimitKey, 1, 300);
                if (!inRateLimit) {
                    //logger.info("--inRateLimit false. tradeno={}",alipayDetail.getTradeno());
                    continue;
                }

                if (pyqJob.getId().longValue() > idStart.longValue()) {
                    idStart = pyqJob.getId();
                }

                try {

                    //先查询该朋友圈明细
                    String uzai_pyq_job_detail = merchantService.getMechantOtherEsIndexName(EsIndexName.UZAI_PYQ_JOB_DETAIL, pyqJob.getMerId());

                    //删除朋友圈任务
                    pyqJobMapper.deleteById(pyqJob.getId(), pyqJob.getMerId());
                    //清空所有的发送明细
                    DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest();
                    deleteByQueryRequest.setQuery(new TermQueryBuilder("jobId", pyqJob.getId()));
                    try {
                        //批量删除
                        elasticsearchUtilGroupMsg.deleteDataByQuerySingle(uzai_pyq_job_detail, deleteByQueryRequest);
                    } catch (Exception e) {
                        logger.error("删除朋友圈明细请求出现异常,index=" + EsIndexName.UZAI_WECHAT_REQ_USER);
                        throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "删除失败");
                    }

                } catch (Exception e) {
                    logger.error("--调用自动删除历史朋友圈任务--error={}", e.getMessage());
                } finally {
                    //保存成功之后，手动删除限流redisKey
                    redisTemplate.delete(rateLimitKey);
                }
            }

            pyqJobQuery.setIdStart(idStart);
            pyqJobList = pyqJobMapper.findByList(page, pyqJobQuery);

        }
    }

    /**
     * 自动发送发单
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void autoSendFdSync() {

        //限流key
        String taskLimitKet = "-autoSendFdSync-taskLimitKey-";
        Object object = redisTemplate.opsForValue().get(taskLimitKet);
        if (object != null) {
            return;
        }
        //保存限流key
        redisTemplate.opsForValue().set(taskLimitKet, taskLimitKet, 30, TimeUnit.MINUTES);

        logger.info("-----调用自动发送发单任务--xxlJob start--");

        try {
            //查询当前所有开启的自动发圈的配置方案
            int now = DateUtil.getNowTime();
            //提前发送预留时间
            int frontMinutes = 5;

            //当前时间
            LocalDateTime now_localDateTime = LocalDateTime.now();

            String yyyyMMdd = Tools.getDateFormat(new Date(), "yyyy-MM-dd");

            FdAutoConfigQuery fdAutoConfigQuery = new FdAutoConfigQuery();
            fdAutoConfigQuery.setStatus(1); //启动

            //查询所有的自动发圈配置记录
            Page<FdAutoConfig> page = new Page<>();
            page.setCurrent(1);//只查第一页
            page.setSize(10); //每页查询10个
            page.addOrder(OrderItem.asc("id"));//默认id升序
            Long idStart = 0L;
            List<FdAutoConfig> fdAutoConfigList = fdAutoConfigMapper.findByList(page, fdAutoConfigQuery);
            while (fdAutoConfigList != null && fdAutoConfigList.size() > 0) {
                for (FdAutoConfig fdAutoConfig : fdAutoConfigList) {
                    //限流判断
                    String rateLimitKey = "autoSendFd-configId=" + fdAutoConfig.getId();
                    boolean inRateLimit = ratelimitService.inRateLimit(rateLimitKey, 1, 3600);
                    if (!inRateLimit) {
                        //logger.info("--inRateLimit false. tradeno={}",alipayDetail.getTradeno());
                        continue;
                    }

                    try {

                        if (fdAutoConfig.getId().longValue() > idStart.longValue()) {
                            idStart = fdAutoConfig.getId();
                        }

                        //开始限制时间（HH:mm）
                        String limitTimeStart = fdAutoConfig.getLimitTimeStart();
                        if (StringUtils.isBlank(limitTimeStart)) {
                            limitTimeStart = "00:00";
                        }

                        //允许发送区间开始时间=提前5分钟
                        LocalTime limitTimeStartLocal = LocalTime.parse(limitTimeStart).minusMinutes(frontMinutes);
                        //允许发送区间结束时间=延后5分钟
                        LocalTime limitTimeEndLocal = LocalTime.parse(limitTimeStart).plusMinutes(frontMinutes);

                        //判断当前时间是否在自动任务开启时间区间内
                        boolean withinTimeInterval = Tools.isWithinTimeInterval(now_localDateTime, limitTimeStartLocal, limitTimeEndLocal);
                        //不在区间内，则跳过
                        if (!withinTimeInterval) {
                            continue;
                        }
                        //发送间隔最小时间
                        Integer rateMin = 24 * 60 * 60; //最少1天
                        //上次发送时间
                        Integer sendTime = Tools.getInteger(fdAutoConfig.getSendTime());
                        if (sendTime.intValue() != 0) { //已经开始发送配置方案
                            if (sendTime.intValue() + rateMin.intValue() - frontMinutes * 60 > now) {//上次发送时间+最小时间间隔，如果还大于当前时间，表示还未轮到，
                                continue;
                            }
                        }

                        //这次发送时间,当天日期+设置的发送时间
                        String sendTimeNewStr = DateUtil.today() + " " + limitTimeStart + ":00";
                        int sendTimeNew = (int) (DateUtil.parse(sendTimeNewStr, "yyyy-MM-dd HH:mm:ss").getTime() / 1000L);

                        //更新新的发送时间
                        fdAutoConfig.setSendTime(sendTimeNew);

                        //自动发送发单
                        fdAutoSendService.autoSendFd(fdAutoConfig);

                    } catch (Exception e) {
                        logger.error("--自动发单失败--error={}", e.getMessage());
                    } finally {
                        //保存成功之后，手动删除限流redisKey
                        redisTemplate.delete(rateLimitKey);
                    }
                }

                fdAutoConfigQuery.setIdStart(idStart);
                fdAutoConfigList = fdAutoConfigMapper.findByList(page, fdAutoConfigQuery);

            }
        } catch (Exception e) {
            logger.info(e.getMessage());
        } finally {
            //删除限流key
            redisTemplate.delete(taskLimitKet);
        }
    }

    /**
     * 自动删除历史社群群发信息
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void deleteFdSendJobHistorySync() {
        logger.info("-----调用自动删除历史社群群发信息任务--xxlJob start--");

        //查询当前所有开启的自动发圈的配置方案
        int now = DateUtil.getNowTime();
        //查询历史时间
        int queryEndTime = now - 10 * 24 * 3600;

        FdSendJobQuery fdSendJobQuery = new FdSendJobQuery();
        fdSendJobQuery.setParentId(0L); //只查询主任务
        fdSendJobQuery.setQueryEndTime(queryEndTime); //查询结束时间
        //查询所有的自动发圈配置记录
        Page<FdSendJob> page = new Page<>();
        page.setCurrent(1);//只查第一页
        page.setSize(10); //每页查询10个
        page.addOrder(OrderItem.asc("id"));//默认id升序
        Long idStart = 0L;
        List<FdSendJob> fdSendJobList = fdSendJobMapper.findByList(page, fdSendJobQuery);
        while (fdSendJobList != null && fdSendJobList.size() > 0) {

            //晚上23:30:00之后，跳出线程
            if (Tools.timeCompare("23:30:00")) {
                break;
            }

            for (FdSendJob fdSendJob : fdSendJobList) {
                //限流判断
                String rateLimitKey = "deleteFdSendJobHistorySync-fdSendJobId=" + fdSendJob.getId();
                boolean inRateLimit = ratelimitService.inRateLimit(rateLimitKey, 1, 30);
                if (!inRateLimit) {
                    //logger.info("--inRateLimit false. tradeno={}",alipayDetail.getTradeno());
                    continue;
                }

                if (fdSendJob.getId().longValue() > idStart.longValue()) {
                    idStart = fdSendJob.getId();
                }

                try {
                    if (Tools.getLong(fdSendJob.getParentId()) == 0) { //主任务
                        //删除主任务
                        fdSendJobMapper.deleteById(fdSendJob.getId(), fdSendJob.getMerId());

                        //删除子任务
                        fdSendJobMapper.deleteByParentId(fdSendJob.getId(), fdSendJob.getMerId());

                        //删除群发任务ES数据
                        DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest();
                        deleteByQueryRequest.setQuery(new TermQueryBuilder("parentJobId", fdSendJob.getId()));

                        //查询运营商其他索引分片
                        String uzai_group_send_msg = merchantService.getMechantOtherEsIndexName(EsIndexName.FD_GROUP_SEND_MSG, fdSendJob.getMerId());
                        elasticsearchUtilGroupMsg.deleteDataByQuerySingle(uzai_group_send_msg, deleteByQueryRequest);
                    }
                } catch (Exception e) {
                    logger.error("--调用自动删除历史社群群发信息任务失败--error={}", e.getMessage());
                } finally {
                    //保存成功之后，手动删除限流redisKey
                    redisTemplate.delete(rateLimitKey);
                }
            }

            fdSendJobQuery.setIdStart(idStart);
            fdSendJobList = fdSendJobMapper.findByList(page, fdSendJobQuery);

        }
    }


    /**
     * 自动下载淘宝处罚订单
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void autoDownloadTbPunishOrder() {
        logger.info("-----自动下载淘宝处罚订单--xxlJob start--");

        //当前时间格式
        String currentTime = Tools.getDateFormat(new Date(), "yyyy-MM-dd HH:mm:ss");
        logger.info("---自动下载淘宝处罚订单时间currentTime={}", currentTime);

        //查询当前所有朋友圈评论列表
        TbTokenQuery tbTokenQuery = new TbTokenQuery();
        tbTokenQuery.setType(0); //淘宝
        tbTokenQuery.setExpireType(1); //未到期

        //查询所有的pyq评论记录
        Page<TbToken> page = new Page<>();
        page.setCurrent(1);//只查第一页
        page.setSize(10); //每页查询10个
        page.addOrder(OrderItem.asc("id"));//默认id升序
        Long idStart = 0L;
        List<TbToken> tbTokenList = tbTokenMapper.findByList(page, tbTokenQuery);
        //返利
        String tbApiUrl = uzaiConsoleSysConfig.getTbApiUrl();
        String tbAppkey = uzaiConsoleSysConfig.getTbAppkey();
        String tbAppsecret = uzaiConsoleSysConfig.getTbAppsecret();
        TaobaoClient client = new DefaultTaobaoClient(tbApiUrl, tbAppkey, tbAppsecret);
        //导购
        String tbApiUrl_dg = uzaiConsoleSysConfig.getTbApiUrl();
        String tbAppkey_dg = uzaiConsoleSysConfig.getTbAppkeyDg();
        String tbAppsecret_dg = uzaiConsoleSysConfig.getTbAppsecretDg();
        TaobaoClient client_dg = new DefaultTaobaoClient(tbApiUrl_dg, tbAppkey_dg, tbAppsecret_dg);

        while (tbTokenList != null && tbTokenList.size() > 0) {
            for (TbToken tbToken : tbTokenList) {
                try {
                    if (tbToken.getId().longValue() > idStart.longValue()) {
                        idStart = tbToken.getId();
                    }

                    //限流判断
                    String rateLimitKey = "autoDownloadTbPunishOrder-tbTokenId=" + tbToken.getId();
                    boolean inRateLimit = ratelimitService.inRateLimit(rateLimitKey, 1, 30);
                    if (!inRateLimit) {
                        //logger.info("--inRateLimit false. tradeno={}",alipayDetail.getTradeno());
                        continue;
                    }

                    //每天晚上下载90天前的处罚订单
                    String specifiedDayBefore = Tools.getSpecifiedDayBefore(currentTime, "yyyy-MM-dd HH:mm:ss", 89);

                    //导购联盟
                    if (Tools.getInteger(tbToken.getTurnlink()).intValue() == 0) {
                        //处理淘宝处罚订单
                        tbPunishOrderService.dealTbPunishOrder(client, specifiedDayBefore, tbToken);
                    } else {//导购
                        //处理淘宝处罚订单
                        tbPunishOrderService.dealTbPunishOrder(client_dg, specifiedDayBefore, tbToken);
                    }
                    //保存成功之后，手动删除限流redisKey
                    redisTemplate.delete(rateLimitKey);
                } catch (Exception e) {
                    logger.error("--自动下载淘宝处罚订单-tokenId={},error={}", tbToken.getId(), e.getMessage());
                }
            }

            tbTokenQuery.setIdStart(idStart);
            tbTokenList = tbTokenMapper.findByList(page, tbTokenQuery);
        }
    }

    /**
     * 合并机器人电脑端和移动端授权数据任务
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void handerDeviceAuthForPcAndMobile() {
        logger.info("-----合并机器人电脑端和移动端授权数据任务--xxlJob start--");

        //查询当前所有朋友圈评论列表
        DeviceAuthQuery deviceAuthQuery = new DeviceAuthQuery();
        deviceAuthQuery.setDeviceTypeId(1); //查询移动端

        //查询所有的pyq评论记录
        Page<DeviceAuth> page = new Page<>();
        page.setCurrent(1);//只查第一页
        page.setSize(10); //每页查询10个
        page.addOrder(OrderItem.asc("id"));//默认id升序
        Long idStart = 0L;
        List<DeviceAuth> deviceAuthList = deviceAuthMapper.findByList(page, deviceAuthQuery);

        while (deviceAuthList != null && deviceAuthList.size() > 0) {
            for (DeviceAuth deviceAuth : deviceAuthList) {
                try {
                    if (deviceAuth.getId().longValue() > idStart.longValue()) {
                        idStart = deviceAuth.getId();
                    }

                    //限流判断
                    String rateLimitKey = "handerDeviceAuthForPcAndMobile-deviceAuthId=" + deviceAuth.getId();
                    boolean inRateLimit = ratelimitService.inRateLimit(rateLimitKey, 1, 30);
                    if (!inRateLimit) {
                        //logger.info("--inRateLimit false. tradeno={}",alipayDetail.getTradeno());
                        continue;
                    }

                    //查询该授权记录是否有PC端授权，如果没有则把该移动端授权改成PC端授权
                    DeviceAuth deviceAuth_pc = deviceAuthMapper.selectByDeviceIdAndProductCodeAndDeivceTypeId(deviceAuth.getDeviceId(), deviceAuth.getProductCode(), 0);
                    if (deviceAuth_pc == null) { //不存在，则将移动授权变成PC端授权
                        deviceAuth.setDeviceTypeId(0);
                        deviceAuthMapper.updateByIdSelective(deviceAuth);
                    } else {//PC端授权存在，则需要判断授权到期时间，将较大的到期时间保存到PC端授权里，删除移动端授权
                        if (deviceAuth.getExpireTime().intValue() > deviceAuth_pc.getExpireTime().intValue()) {//移动端授权到期时间大于PC端授权到期时间
                            deviceAuth_pc.setExpireTime(deviceAuth.getExpireTime());
                            deviceAuthMapper.updateByIdSelective(deviceAuth_pc);
                        }
                        //删除移动端授权
                        deviceAuthMapper.deleteById(deviceAuth.getId());
                    }
                    //保存成功之后，手动删除限流redisKey
                    redisTemplate.delete(rateLimitKey);
                } catch (Exception e) {
                    logger.error("--合并机器人电脑端和移动端授权数据失败--error={}", e.getMessage());
                }
            }

            deviceAuthQuery.setIdStart(idStart);
            deviceAuthList = deviceAuthMapper.findByList(page, deviceAuthQuery);
        }
    }

    /**
     * 处理企业微信和个人微信的授权出现多份问题
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void handerDeviceAuthForWechantAndWxwork() {
        logger.info("-----合并机器人同一个机器人出现个人微信和企业微信授权数据--xxlJob start--");

        //查询当前所有朋友圈评论列表
        DeviceAuthQuery deviceAuthQuery = new DeviceAuthQuery();
        deviceAuthQuery.setDeviceTypeId(1); //查询移动端

        //查询所有的pyq评论记录
        Page<DeviceAuth> page = new Page<>();
        page.setCurrent(1);//只查第一页
        page.setSize(10); //每页查询10个
        page.addOrder(OrderItem.asc("id"));//默认id升序
        Long idStart = 0L;
        List<DeviceAuthForWechantAndWxworkVo> deviceAuthForWechantAndWxworkVoList = deviceAuthMapper.findByListForWechantAndWxwork();
        if(deviceAuthForWechantAndWxworkVoList != null && deviceAuthForWechantAndWxworkVoList.size() > 0) {
            for (DeviceAuthForWechantAndWxworkVo deviceAuthForWechantAndWxworkVo : deviceAuthForWechantAndWxworkVoList) {
                try {

                    //限流判断
                    String rateLimitKey = "handerDeviceAuthForWechantAndWxwork-deviceAuthId=" + deviceAuthForWechantAndWxworkVo.getDeviceId()+ deviceAuthForWechantAndWxworkVo.getProductCode();
                    boolean inRateLimit = ratelimitService.inRateLimit(rateLimitKey, 1, 30);
                    if (!inRateLimit) {
                        //logger.info("--inRateLimit false. tradeno={}",alipayDetail.getTradeno());
                        continue;
                    }


                    DeviceAuth maxExpireTimeDeviceAuth = null;
                    List<DeviceAuth> deviceAuthList = deviceAuthMapper.selectListByDeviceIdAndProductCode(deviceAuthForWechantAndWxworkVo.getDeviceId(), deviceAuthForWechantAndWxworkVo.getProductCode());
                    if(deviceAuthList != null && deviceAuthList.size() > 0){
                        for (DeviceAuth deviceAuth : deviceAuthList) {
                            if(maxExpireTimeDeviceAuth == null){
                                maxExpireTimeDeviceAuth = deviceAuth;
                            }else{
                                if(maxExpireTimeDeviceAuth.getExpireTime().intValue() < deviceAuth.getExpireTime().intValue()){
                                    maxExpireTimeDeviceAuth = deviceAuth;
                                }
                            }
                        }
                    }

                    for (DeviceAuth deviceAuth : deviceAuthList) {
                        if(maxExpireTimeDeviceAuth.getId().longValue() != deviceAuth.getId()){
                            deviceAuthMapper.deleteById(deviceAuth.getId());
                        }
                    }

                    //保存成功之后，手动删除限流redisKey
                    redisTemplate.delete(rateLimitKey);
                } catch (Exception e) {
                    logger.error("--合并机器人同一个机器人出现个人微信和企业微信授权数据--error={}", e.getMessage());
                }
            }
        }
    }

    /**
     * 刷新企业微信授权
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void refreshDeviceAuthForWxwork() {
        logger.info("-----刷新企业微信授权任务--xxlJob start--");

        //查询当前所有朋友圈评论列表
        //个人微信机器人是否掉线
        DeviceWxworkInfoQuery deviceWxworkInfoQuery = new DeviceWxworkInfoQuery();

        //查询所有机器人
        Page<DeviceWxworkInfo> page = new Page<>();
        page.setCurrent(1);//只查第一页
        page.setSize(10); //每页查询20个
        page.addOrder(OrderItem.asc("id"));//默认id升序
        Long idStart = 0L;

        List<DeviceWxworkInfo> deviceWxworkInfoList = deviceWxworkInfoMapper.findSimpleByList(page, deviceWxworkInfoQuery);

        while (deviceWxworkInfoList != null && deviceWxworkInfoList.size() > 0) {
            for (DeviceWxworkInfo deviceWxworkInfo : deviceWxworkInfoList) {
                try {
                    if (deviceWxworkInfo.getId().longValue() > idStart.longValue()) {
                        idStart = deviceWxworkInfo.getId();
                    }

                    //限流判断
                    String rateLimitKey = "refreshDeviceAuthForWxwork-deviceId=" + deviceWxworkInfo.getId();
                    boolean inRateLimit = ratelimitService.inRateLimit(rateLimitKey, 1, 30);
                    if (!inRateLimit) {
                        //logger.info("--inRateLimit false. tradeno={}",alipayDetail.getTradeno());
                        continue;
                    }

                    //刷新新转移机器人的授权缓存
                    deviceWxworkInfoService.flashDeviceAuth(deviceWxworkInfo);

                    //保存成功之后，手动删除限流redisKey
                    redisTemplate.delete(rateLimitKey);
                } catch (Exception e) {
                    logger.error("--刷新企业微信授权任务失败--error={}", e.getMessage());
                }
            }

            deviceWxworkInfoQuery.setIdStart(idStart);
            deviceWxworkInfoList = deviceWxworkInfoMapper.findSimpleByList(page, deviceWxworkInfoQuery);
        }
    }

    /**
     * 自动清理过期订单
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void handerExpiredOrders() {
        logger.info("-----调用自动清理过期订单任务--xxlJob start--");

        //查询当前所有朋友圈评论列表
        MerBaseConfigQuery merBaseConfigQuery = new MerBaseConfigQuery();
        //数据处理-历史订单状态处理
        merBaseConfigQuery.setKey(MerConfigKeyEnum.DATA_HANDLE_HISTORY_ORDER_STATUS_CLEAN.getValue());

        //查询所有的pyq评论记录
        Page<MerBaseConfig> page = new Page<>();
        page.setCurrent(1);//只查第一页
        page.setSize(10); //每页查询10个
        page.addOrder(OrderItem.asc("id"));//默认id升序
        Long idStart = 0L;
        List<MerBaseConfig> merBaseConfigList = merBaseConfigMapper.findByList(page, merBaseConfigQuery);
        while (merBaseConfigList != null && merBaseConfigList.size() > 0) {
            for (MerBaseConfig merBaseConfig : merBaseConfigList) {
                try {
                    if (merBaseConfig.getId().longValue() > idStart.longValue()) {
                        idStart = merBaseConfig.getId();
                    }

                    //限流判断
                    String rateLimitKey = "handerExpiredOrders-merBaseConfigId=" + merBaseConfig.getId();
                    boolean inRateLimit = ratelimitService.inRateLimit(rateLimitKey, 1, 30);
                    if (!inRateLimit) {
                        //logger.info("--inRateLimit false. tradeno={}",alipayDetail.getTradeno());
                        continue;
                    }

                    List<HandExpiredOrdersConfigJson> handExpiredOrdersConfigJsonList = JSONObject.parseArray(merBaseConfig.getVal(), HandExpiredOrdersConfigJson.class);
                    if (handExpiredOrdersConfigJsonList != null && handExpiredOrdersConfigJsonList.size() > 0) {
                        for (HandExpiredOrdersConfigJson handExpiredOrdersConfigJson : handExpiredOrdersConfigJsonList) {
                            if (handExpiredOrdersConfigJson.getEnable() == 1) {
                                //增加运营商报表改变记录
                                //查询提现记录报表记录存不存在，存在则不添加
                                MerReportChange merReportChange = merReportChangeMapper.selectByMerIdAndType(merBaseConfig.getMerId(), 1);
                                if (merReportChange == null) {
                                    merReportChange = new MerReportChange();
                                    merReportChange.setId(IdWorker.getId());
                                    merReportChange.setMerId(IdWorker.getId());
                                    merReportChange.setType(1);
                                    merReportChange.setRemark("数据处理-自动订单清理");
                                    merReportChange.setCreateTime(DateUtil.getNowTime());
                                    merReportChange.setUpdateTime(DateUtil.getNowTime());
                                    merReportChangeMapper.insert(merReportChange);
                                }
                            }

                            //订单类型, 1: 淘宝, 2: 京东, 3: 拼多多, 4: 唯品会, 5: 抖音, 6: 美团, 7: 饿了么; 8：快手
                            int type = handExpiredOrdersConfigJson.getType();
                            if (type == 1) { //淘宝
                                if (handExpiredOrdersConfigJson.getEnable() == 1) {//启用
                                    int day = handExpiredOrdersConfigJson.getDay();
                                    //订单状态, 2: 失效, 1: 结算
                                    Integer status = Tools.getInteger(handExpiredOrdersConfigJson.getStatus());
                                    if (status == null) {//如果订单状态为空，则默认改为订单结算（兼容旧版）
                                        status = 1; //
                                    }
                                    //修改成结算，需要判断按实际结算，还是只修改订单状态
                                    if (status == 1) {
                                        if (handExpiredOrdersConfigJson.getSettle() == 0) { //不结算，直接订单状态为已经结算
                                            tbOrderSyncService.uploadTbOrderSettingSync(merBaseConfig.getMerId(), day, status, handExpiredOrdersConfigJson.getSourceStatus());
                                        } else if (handExpiredOrdersConfigJson.getSettle() == 1) {//结算，重新请求同步订单接口
                                            //来源状态(涉及两个字段), 1: 未收货 - 订单状态, 2: 冻结 - 订单返利状态
                                            List<Integer> sourceStatus = handExpiredOrdersConfigJson.getSourceStatus();
                                            if (sourceStatus != null && sourceStatus.size() > 0) {
                                                //未收货订单
                                                if (sourceStatus.contains(1)) {
                                                    tbOrderSyncService.updateTbOrderUnReceivedListSync(merBaseConfig.getMerId(), day);
                                                }
                                                //冻结订单
                                                if (sourceStatus.contains(2)) {
                                                    tbOrderSyncService.updateTbOrderFreezedListSync(merBaseConfig.getMerId(), day);
                                                }
                                                //维权中
                                                if (sourceStatus.contains(3)) {
                                                    tbOrderSyncService.updateTbOrderRefundingListSync(merBaseConfig.getMerId(), day);
                                                }
                                            }
                                        }
                                    } else if (status == 2) {//修改成失效，则只需要修改订单状态，无需实际结算
                                        tbOrderSyncService.uploadTbOrderSettingSync(merBaseConfig.getMerId(), day, status, handExpiredOrdersConfigJson.getSourceStatus());
                                    }
                                }
                            } else if (type == 2) { //京东
                                if (handExpiredOrdersConfigJson.getEnable() == 1) {//启用
                                    int day = handExpiredOrdersConfigJson.getDay();
                                    //订单状态, 2: 失效, 1: 结算
                                    Integer status = Tools.getInteger(handExpiredOrdersConfigJson.getStatus());
                                    if (status == null) {//如果订单状态为空，则默认改为订单结算（兼容旧版）
                                        status = 1; //
                                    }
                                    //修改成结算，需要判断按实际结算，还是只修改订单状态
                                    if (status == 1) {
                                        if (handExpiredOrdersConfigJson.getSettle() == 0) { //不结算，直接订单状态为已经结算
                                            jdOrderSyncService.uploadJdOrderSettingSync(merBaseConfig.getMerId(), day, status, handExpiredOrdersConfigJson.getSourceStatus());
                                        } else if (handExpiredOrdersConfigJson.getSettle() == 1) {//结算，重新请求同步订单接口
                                            //来源状态(涉及两个字段), 1: 未收货 - 订单状态, 2: 冻结 - 订单返利状态
                                            List<Integer> sourceStatus = handExpiredOrdersConfigJson.getSourceStatus();
                                            if (sourceStatus != null && sourceStatus.size() > 0) {
                                                //未收货订单
                                                if (sourceStatus.contains(1)) {
                                                    jdOrderSyncService.updateJdOrderUnReceivedListSync(merBaseConfig.getMerId(), day);
                                                }
                                                //冻结订单
                                                if (sourceStatus.contains(2)) {
                                                    jdOrderSyncService.updateJdOrderFreezedListSync(merBaseConfig.getMerId(), day);
                                                }
                                                //维权中订单
                                                if (sourceStatus.contains(3)) {
                                                    jdOrderSyncService.updateJdOrderRefundingListSync(merBaseConfig.getMerId(), day);
                                                }
                                            }
                                        }
                                    } else if (status == 2) {//修改成失效，则只需要修改订单状态，无需实际结算
                                        jdOrderSyncService.uploadJdOrderSettingSync(merBaseConfig.getMerId(), day, status, handExpiredOrdersConfigJson.getSourceStatus());
                                    }
                                }
                            } else if (type == 3) { //拼多多
                                if (handExpiredOrdersConfigJson.getEnable() == 1) {//启用
                                    int day = handExpiredOrdersConfigJson.getDay();
                                    //订单状态, 2: 失效, 1: 结算
                                    Integer status = Tools.getInteger(handExpiredOrdersConfigJson.getStatus());
                                    if (status == null) {//如果订单状态为空，则默认改为订单结算（兼容旧版）
                                        status = 1; //
                                    }
                                    //修改成结算，需要判断按实际结算，还是只修改订单状态
                                    if (status == 1) {
                                        if (handExpiredOrdersConfigJson.getSettle() == 0) { //不结算，直接订单状态为已经结算
                                            pddOrderSyncService.uploadPddOrderSettingSync(merBaseConfig.getMerId(), day, status, handExpiredOrdersConfigJson.getSourceStatus());
                                        } else if (handExpiredOrdersConfigJson.getSettle() == 1) {//结算，重新请求同步订单接口
                                            //来源状态(涉及两个字段), 1: 未收货 - 订单状态, 2: 冻结 - 订单返利状态
                                            List<Integer> sourceStatus = handExpiredOrdersConfigJson.getSourceStatus();
                                            if (sourceStatus != null && sourceStatus.size() > 0) {
                                                //未收货订单
                                                if (sourceStatus.contains(1)) {
                                                    pddOrderSyncService.updatePddOrderUnReceivedListSync(merBaseConfig.getMerId(), day);
                                                }
                                                //冻结订单
                                                if (sourceStatus.contains(2)) {
                                                    pddOrderSyncService.updatePddOrderFreezedListSync(merBaseConfig.getMerId(), day);
                                                }
                                                //维权中订单
                                                if (sourceStatus.contains(3)) {
                                                    pddOrderSyncService.updatePddOrderRefundingListSync(merBaseConfig.getMerId(), day);
                                                }
                                            }
                                        }
                                    } else if (status == 2) {//修改成失效，则只需要修改订单状态，无需实际结算
                                        pddOrderSyncService.uploadPddOrderSettingSync(merBaseConfig.getMerId(), day, status, handExpiredOrdersConfigJson.getSourceStatus());
                                    }
                                }
                            } else if (type == 4) { //唯品会
                                if (handExpiredOrdersConfigJson.getEnable() == 1) {//启用
                                    int day = handExpiredOrdersConfigJson.getDay();
                                    //订单状态, 2: 失效, 1: 结算
                                    Integer status = Tools.getInteger(handExpiredOrdersConfigJson.getStatus());
                                    if (status == null) {//如果订单状态为空，则默认改为订单结算（兼容旧版）
                                        status = 1; //
                                    }
                                    //修改成结算，需要判断按实际结算，还是只修改订单状态
                                    if (status == 1) {
                                        if (handExpiredOrdersConfigJson.getSettle() == 0) { //不结算，直接订单状态为已经结算
                                            vphOrderSyncService.uploadVphOrderSettingSync(merBaseConfig.getMerId(), day, status, handExpiredOrdersConfigJson.getSourceStatus());
                                        } else if (handExpiredOrdersConfigJson.getSettle() == 1) {//结算，重新请求同步订单接口
                                            //来源状态(涉及两个字段), 1: 未收货 - 订单状态, 2: 冻结 - 订单返利状态
                                            List<Integer> sourceStatus = handExpiredOrdersConfigJson.getSourceStatus();
                                            if (sourceStatus != null && sourceStatus.size() > 0) {
                                                //未收货订单
                                                if (sourceStatus.contains(1)) {
                                                    vphOrderSyncService.updateVphOrderUnReceivedListSync(merBaseConfig.getMerId(), day);
                                                }
                                                //冻结订单
                                                if (sourceStatus.contains(2)) {
                                                    vphOrderSyncService.updateVphOrderFreezedListSync(merBaseConfig.getMerId(), day);
                                                }
                                                //维权中订单
                                                if (sourceStatus.contains(3)) {
                                                    vphOrderSyncService.updateVphOrderRefundingListSync(merBaseConfig.getMerId(), day);
                                                }
                                            }
                                        }
                                    } else if (status == 2) {//修改成失效，则只需要修改订单状态，无需实际结算
                                        vphOrderSyncService.uploadVphOrderSettingSync(merBaseConfig.getMerId(), day, status, handExpiredOrdersConfigJson.getSourceStatus());
                                    }
                                }
                            } else if (type == 5) { //抖音
                                if (handExpiredOrdersConfigJson.getEnable() == 1) {//启用
                                    int day = handExpiredOrdersConfigJson.getDay();
                                    //订单状态, 2: 失效, 1: 结算
                                    Integer status = Tools.getInteger(handExpiredOrdersConfigJson.getStatus());
                                    if (status == null) {//如果订单状态为空，则默认改为订单结算（兼容旧版）
                                        status = 1; //
                                    }
                                    //修改成结算，需要判断按实际结算，还是只修改订单状态
                                    if (status == 1) {
                                        if (handExpiredOrdersConfigJson.getSettle() == 0) { //不结算，直接订单状态为已经结算
                                            dyOrderSyncService.uploadDyOrderSettingSync(merBaseConfig.getMerId(), day, status, handExpiredOrdersConfigJson.getSourceStatus());
                                        } else if (handExpiredOrdersConfigJson.getSettle() == 1) {//结算，重新请求同步订单接口
                                            //来源状态(涉及两个字段), 1: 未收货 - 订单状态, 2: 冻结 - 订单返利状态
                                            List<Integer> sourceStatus = handExpiredOrdersConfigJson.getSourceStatus();
                                            if (sourceStatus != null && sourceStatus.size() > 0) {
                                                //未收货订单
                                                if (sourceStatus.contains(1)) {
                                                    dyOrderSyncService.updateDyOrderUnReceivedListSync(merBaseConfig.getMerId(), day);
                                                }
                                                //冻结订单
                                                if (sourceStatus.contains(2)) {
                                                    dyOrderSyncService.updateDyOrderFreezedListSync(merBaseConfig.getMerId(), day);
                                                }
                                                //维权中订单
                                                if (sourceStatus.contains(3)) {
                                                    dyOrderSyncService.updateDyOrderRefundingListSync(merBaseConfig.getMerId(), day);
                                                }
                                            }
                                        }
                                    } else if (status == 2) {//修改成失效，则只需要修改订单状态，无需实际结算
                                        dyOrderSyncService.uploadDyOrderSettingSync(merBaseConfig.getMerId(), day, status, handExpiredOrdersConfigJson.getSourceStatus());
                                    }
                                }
                            } else if (type == 6) { //美团
                                if (handExpiredOrdersConfigJson.getEnable() == 1) {//启用
                                    int day = handExpiredOrdersConfigJson.getDay();
                                    //订单状态, 2: 失效, 1: 结算
                                    Integer status = Tools.getInteger(handExpiredOrdersConfigJson.getStatus());
                                    if (status == null) {//如果订单状态为空，则默认改为订单结算（兼容旧版）
                                        status = 1; //
                                    }
                                    //修改成结算，需要判断按实际结算，还是只修改订单状态
                                    if (status == 1) {
                                        if (handExpiredOrdersConfigJson.getSettle() == 0) { //不结算，直接订单状态为已经结算
                                            mtOrderSyncService.uploadMtOrderSettingSync(merBaseConfig.getMerId(), day, status, handExpiredOrdersConfigJson.getSourceStatus());
                                        } else if (handExpiredOrdersConfigJson.getSettle() == 1) {//结算，重新请求同步订单接口
                                            //来源状态(涉及两个字段), 1: 未收货 - 订单状态, 2: 冻结 - 订单返利状态
                                            List<Integer> sourceStatus = handExpiredOrdersConfigJson.getSourceStatus();
                                            if (sourceStatus != null && sourceStatus.size() > 0) {
                                                //未收货订单
                                                if (sourceStatus.contains(1)) {
                                                    mtOrderSyncService.updateMtOrderUnReceivedListSync(merBaseConfig.getMerId(), day);
                                                }
                                                //冻结订单
                                                if (sourceStatus.contains(2)) {
                                                    mtOrderSyncService.updateMtOrderFreezedListSync(merBaseConfig.getMerId(), day);
                                                }
                                                //维权中订单
                                                if (sourceStatus.contains(3)) {
                                                    mtOrderSyncService.updateMtOrderRefundingListSync(merBaseConfig.getMerId(), day);
                                                }
                                            }
                                        }
                                    } else if (status == 2) {//修改成失效，则只需要修改订单状态，无需实际结算
                                        mtOrderSyncService.uploadMtOrderSettingSync(merBaseConfig.getMerId(), day, status, handExpiredOrdersConfigJson.getSourceStatus());
                                    }
                                }
                            } else if (type == 7) { //饿了么
                                if (handExpiredOrdersConfigJson.getEnable() == 1) {//启用
                                    int day = handExpiredOrdersConfigJson.getDay();
                                    //订单状态, 2: 失效, 1: 结算
                                    Integer status = Tools.getInteger(handExpiredOrdersConfigJson.getStatus());
                                    if (status == null) {//如果订单状态为空，则默认改为订单结算（兼容旧版）
                                        status = 1; //
                                    }
                                    //修改成结算，需要判断按实际结算，还是只修改订单状态
                                    if (status == 1) {
                                        if (handExpiredOrdersConfigJson.getSettle() == 0) { //不结算，直接订单状态为已经结算
                                            elmOrderSyncService.uploadElmOrderSettingSync(merBaseConfig.getMerId(), day, status, handExpiredOrdersConfigJson.getSourceStatus());
                                        } else if (handExpiredOrdersConfigJson.getSettle() == 1) {//结算，重新请求同步订单接口
                                            //来源状态(涉及两个字段), 1: 未收货 - 订单状态, 2: 冻结 - 订单返利状态
                                            List<Integer> sourceStatus = handExpiredOrdersConfigJson.getSourceStatus();
                                            if (sourceStatus != null && sourceStatus.size() > 0) {
                                                //未收货订单
                                                if (sourceStatus.contains(1)) {
                                                    elmOrderSyncService.updateElmOrderUnReceivedListSync(merBaseConfig.getMerId(), day);
                                                }
                                                //冻结订单
                                                if (sourceStatus.contains(2)) {
                                                    elmOrderSyncService.updateElmOrderFreezedListSync(merBaseConfig.getMerId(), day);
                                                }
                                                //维权中订单
                                                if (sourceStatus.contains(3)) {
                                                    elmOrderSyncService.updateElmOrderRefundingListSync(merBaseConfig.getMerId(), day);
                                                }
                                            }
                                        }
                                    } else if (status == 2) {//修改成失效，则只需要修改订单状态，无需实际结算
                                        elmOrderSyncService.uploadElmOrderSettingSync(merBaseConfig.getMerId(), day, status, handExpiredOrdersConfigJson.getSourceStatus());
                                    }
                                }
                            } else if (type == 8) { //快手
                                if (handExpiredOrdersConfigJson.getEnable() == 1) {//启用
                                    int day = handExpiredOrdersConfigJson.getDay();
                                    //订单状态, 2: 失效, 1: 结算
                                    Integer status = Tools.getInteger(handExpiredOrdersConfigJson.getStatus());
                                    if (status == null) {//如果订单状态为空，则默认改为订单结算（兼容旧版）
                                        status = 1; //
                                    }
                                    //修改成结算，需要判断按实际结算，还是只修改订单状态
                                    if (status == 1) {
                                        if (handExpiredOrdersConfigJson.getSettle() == 0) { //不结算，直接订单状态为已经结算
                                            ksOrderSyncService.uploadKsOrderSettingSync(merBaseConfig.getMerId(), day, status, handExpiredOrdersConfigJson.getSourceStatus());
                                        } else if (handExpiredOrdersConfigJson.getSettle() == 1) {//结算，重新请求同步订单接口
                                            //来源状态(涉及两个字段), 1: 未收货 - 订单状态, 2: 冻结 - 订单返利状态
                                            List<Integer> sourceStatus = handExpiredOrdersConfigJson.getSourceStatus();
                                            if (sourceStatus != null && sourceStatus.size() > 0) {
                                                //未收货订单
                                                if (sourceStatus.contains(1)) {
                                                    ksOrderSyncService.updateKsOrderUnReceivedListSync(merBaseConfig.getMerId(), day);
                                                }
                                                //冻结订单
                                                if (sourceStatus.contains(2)) {
                                                    ksOrderSyncService.updateKsOrderFreezedListSync(merBaseConfig.getMerId(), day);
                                                }
                                                //维权中订单
                                                if (sourceStatus.contains(3)) {
                                                    ksOrderSyncService.updateKsOrderRefundingListSync(merBaseConfig.getMerId(), day);
                                                }
                                            }
                                        }
                                    } else if (status == 2) {//修改成失效，则只需要修改订单状态，无需实际结算
                                        ksOrderSyncService.uploadKsOrderSettingSync(merBaseConfig.getMerId(), day, status, handExpiredOrdersConfigJson.getSourceStatus());
                                    }
                                }
                            }
                        }
                    }

                    //保存成功之后，手动删除限流redisKey
                    redisTemplate.delete(rateLimitKey);
                } catch (Exception e) {
                    logger.error("--处理过期订单数据失败--error={}", e.getMessage());
                }
            }

            merBaseConfigQuery.setIdStart(idStart);
            merBaseConfigList = merBaseConfigMapper.findByList(page, merBaseConfigQuery);
        }
    }

    /**
     * 清除无效的发单商品参数变量-没有发单模板在使用
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void handerFdGoodsPara() {
        logger.info("-----调用自动清理无效的发单商品参数变量任务--xxlJob start--");

        //查询当前所有朋友圈评论列表
        FdGoodsParaQuery fdGoodsParaQuery = new FdGoodsParaQuery();

        //查询所有的pyq评论记录
        Page<FdGoodsPara> page = new Page<>();
        page.setCurrent(1);//只查第一页
        page.setSize(10); //每页查询10个
        page.addOrder(OrderItem.asc("id"));//默认id升序
        Long idStart = 0L;
        List<FdGoodsPara> fdGoodsParaList = fdGoodsParaMapper.findByList(page, fdGoodsParaQuery);
        while (fdGoodsParaList != null && fdGoodsParaList.size() > 0) {
            for (FdGoodsPara fdGoodsPara : fdGoodsParaList) {
                try {
                    if (fdGoodsPara.getId().longValue() > idStart.longValue()) {
                        idStart = fdGoodsPara.getId();
                    }
                    //限流判断
                    String rateLimitKey = "handerFdGoodsPara-fdGoodsParaId=" + fdGoodsPara.getId();
                    boolean inRateLimit = ratelimitService.inRateLimit(rateLimitKey, 1, 30);
                    if (!inRateLimit) {
                        //logger.info("--inRateLimit false. tradeno={}",alipayDetail.getTradeno());
                        continue;
                    }
                    //判断这个发单商品是否给发单模板使用，如果没有被使用，则删除
                    FdTemplateQuery fdTemplateQuery = new FdTemplateQuery();
                    fdTemplateQuery.setMerId(fdGoodsPara.getMerId());
                    fdTemplateQuery.setFdGoodsParaId(fdGoodsPara.getId());
                    ArrayList<FdTemplate> fdTemplateList = fdTemplateMapper.findByList(fdTemplateQuery);
                    if (fdTemplateList == null || fdTemplateList.size() == 0) { //未找到发单模板配置了该商品，则删除
                        fdGoodsParaMapper.deleteById(fdGoodsPara.getId(), fdGoodsPara.getMerId());
                    }
                    //保存成功之后，手动删除限流redisKey
                    redisTemplate.delete(rateLimitKey);
                } catch (Exception e) {
                    logger.error("--处理自动清理无效的发单商品参数数据失败--error={}", e.getMessage());
                }
            }

            fdGoodsParaQuery.setIdStart(idStart);
            fdGoodsParaList = fdGoodsParaMapper.findByList(page, fdGoodsParaQuery);
        }
    }

    /**
     * 处理互通插件和公众号关联的机器人的插件的merId和配置方案不一样的问题
     * 此方法已经废弃，不能使用
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void handerConfigAndPluginMerIdDifferent() {
//        logger.info("-----处理互通插件和公众号关联的机器人的插件的merId和配置方案不一样的的线程--xxlJob start--");
//
//        //限流判断
//        String rateLimitKey = "handerConfigAndPluginMerIdDifferent-task";
//        boolean inRateLimit = ratelimitService.inRateLimit(rateLimitKey,1,300);
//        if (!inRateLimit){
//            //logger.info("--inRateLimit false. tradeno={}",alipayDetail.getTradeno());
//            return;
//        }
//
//        //查询当前公众号设置插件的运营商id与配置方案的运营商id不一致
//        List<SysPluginDifferentConfigPlanMerIdVo> sysPluginList_wxpubSettingId = sysPluginMapper.handerConfigAndPluginMerIdDifferent("wxpub_setting_id");
//        if(sysPluginList_wxpubSettingId != null && sysPluginList_wxpubSettingId.size() > 0){
//            for (SysPluginDifferentConfigPlanMerIdVo sysPluginDifferentConfigPlanMerIdVo_wxpubSettingId : sysPluginList_wxpubSettingId) {
//                //修改插件的运营商id为配置方案的运营商id
//                sysPluginMapper.updateMerIdById(sysPluginDifferentConfigPlanMerIdVo_wxpubSettingId);
//            }
//        }
//
//        //查询当前公众号互通插件的运营商id与配置方案的运营商id不一致
//        List<SysPluginDifferentConfigPlanMerIdVo> sysPluginList_wechatUnionWxpubId = sysPluginMapper.handerConfigAndPluginMerIdDifferent("wechat_union_wxpub_id");
//        if(sysPluginList_wechatUnionWxpubId != null && sysPluginList_wechatUnionWxpubId.size() > 0){
//            for (SysPluginDifferentConfigPlanMerIdVo sysPluginDifferentConfigPlanMerIdVo_wechatUnionWxpubId : sysPluginList_wechatUnionWxpubId) {
//                //修改插件的运营商id为配置方案的运营商id
//                sysPluginMapper.updateMerIdById(sysPluginDifferentConfigPlanMerIdVo_wechatUnionWxpubId);
//            }
//        }
//
//        //保存成功之后，手动删除限流redisKey
//        redisTemplate.delete(rateLimitKey);
    }

    /**
     * 自动更新抖客账号联盟
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void autoRefreshDyTokenAuth() {

        //限流key
        String taskLimitKet = "-autoRefreshDyTokenAuth-taskLimitKey-";
        Object object = redisTemplate.opsForValue().get(taskLimitKet);
        if (object != null) {
            return;
        }
        //保存限流key
        redisTemplate.opsForValue().set(taskLimitKet, taskLimitKet, 30, TimeUnit.MINUTES);

        logger.info("-----自动刷新抖客账号联盟授权--xxlJob start--");

        try {
            //查询当前所有朋友圈评论列表
            DyTokenQuery dyTokenQuery = new DyTokenQuery();
            dyTokenQuery.setType(1); //抖客联盟账号
            dyTokenQuery.setTokenType(0);
            //dyTokenQuery.setExpireType(1); //未到期

            //查询所有的pyq评论记录
            Page<DyToken> page = new Page<>();
            page.setCurrent(1);//只查第一页
            page.setSize(10); //每页查询10个
            page.addOrder(OrderItem.asc("id"));//默认id升序
            Long idStart = 0L;
            List<DyToken> dyTokenList = dyTokenMapper.findByList(page, dyTokenQuery);

            while (dyTokenList != null && dyTokenList.size() > 0) {
                for (DyToken dyToken : dyTokenList) {
                    try {
                        if (dyToken.getId().longValue() > idStart.longValue()) {
                            idStart = dyToken.getId();
                        }

                        //限流判断
                        String rateLimitKey = "autoRefreshDyTokenAuth-dyTokenId=" + dyToken.getId();
                        boolean inRateLimit = ratelimitService.inRateLimit(rateLimitKey, 1, 30);
                        if (!inRateLimit) {
                            //logger.info("--inRateLimit false. tradeno={}",alipayDetail.getTradeno());
                            continue;
                        }
                        //刷新抖客账号授权
                        dyTokenService.refreshDyTokenAuth(dyToken);
                        //保存成功之后，手动删除限流redisKey
                        redisTemplate.delete(rateLimitKey);
                    } catch (Exception e) {
                        logger.error("--刷新抖客账号授权失败--error={}", e.getMessage());
                    }
                }

                dyTokenQuery.setIdStart(idStart);
                dyTokenList = dyTokenMapper.findByList(page, dyTokenQuery);
            }
        } catch (Exception e) {
            logger.info(e.getMessage());
        } finally {
            //删除限流key
            redisTemplate.delete(taskLimitKet);
        }

    }

    /**
     * 自动刷新个人微信通讯录
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void refreshWxcontacts() {
        logger.info("-----调用个人微信刷新通讯录线程----");

        Integer reFreshWxcontactsNum = uzaiConsoleSysConfig.getReFreshWxcontactsNum();
        if (reFreshWxcontactsNum == null) {
            reFreshWxcontactsNum = 20;
        }

        //个人微信机器人是否掉线
        DeviceWechatInfoQuery deviceWechatInfoQuery = new DeviceWechatInfoQuery();
        //查询所有机器人
        Page<DeviceWechatInfo> page = new Page<>();
        page.setCurrent(1);//只查第一页
        page.setSize(reFreshWxcontactsNum); //每页查询20个
        page.addOrder(OrderItem.asc("id"));//默认id升序
        Long idStart = 0L;
        List<DeviceWechatInfo> deviceWechatInfoList = deviceWechatInfoMapper.findSimpleByList(page, deviceWechatInfoQuery);
        while (deviceWechatInfoList != null && deviceWechatInfoList.size() > 0) {
            //上次查询时间（第一次为当前时间）
            int lastTime = DateUtil.getNowTime();
            for (DeviceWechatInfo deviceWechatInfo : deviceWechatInfoList) {
                if (deviceWechatInfo.getId().longValue() > idStart.longValue()) {
                    idStart = deviceWechatInfo.getId();
                }

                //限流判断(30秒内判断一次)
                boolean inRateLimit = ratelimitService.inRateLimit("refreshWxcontacts-" + deviceWechatInfo.getId(), 1, 30);
                if (!inRateLimit) {
                    //logger.info("{}:inRateLimit false. deviceUniqueId=", deviceAuth.getDeviceUniqueId());
                    continue;
                }

                //判断设备是否在线
                boolean onlineFlag = false;
                int recvmsgType = Tools.getInteger(deviceWechatInfo.getRecvmsgType()).intValue();
                if (recvmsgType == DeviceTypeEnum.DT_PC_WECHAT_VALUE) {//PC端在线
                    //从缓存中换取个人微信PC端信息
                    Object object_pc = redisTemplate.opsForValue().get(String.format(RedisCacheKeyEnum.DEVICE_INFO_WECHAT_PC.getKey(), deviceWechatInfo.getId()));
                    DeviceInfoPcWeChatCacheDto deviceInfoPcWeChatCacheDto = JSONObject.parseObject(String.valueOf(object_pc), DeviceInfoPcWeChatCacheDto.class);
                    //PC端个人微信信息不为空
                    if (deviceInfoPcWeChatCacheDto != null) {
                        //获取最新心跳时间
                        Integer lastHeartBeatTime = deviceInfoPcWeChatCacheDto.getLastHeartBeatTime();
                        if (lastHeartBeatTime != null) {
                            //在线
                            if (DateUtil.getNowTime() - lastHeartBeatTime.intValue() < Const.Device.HEART_BEAT_OFF_LINE_TIME.intValue()) {
                                onlineFlag = true;
                            }
                        }
                    }
                } else if (recvmsgType == DeviceTypeEnum.DT_ANDROID_WECHAT_VALUE) {//手机端在线
                    //从缓存中获取个人微信手机端信息
                    Object object_mobile = redisTemplate.opsForValue().get(String.format(RedisCacheKeyEnum.DEVICE_INFO_WECHAT_MOBLE.getKey(), deviceWechatInfo.getId()));
                    DeviceInfoMobileWeChatCacheDto deviceInfoMobileWeChatCacheDto = JSONObject.parseObject(String.valueOf(object_mobile), DeviceInfoMobileWeChatCacheDto.class);
                    //移动端个人微信信息不为空
                    if (deviceInfoMobileWeChatCacheDto != null) {
                        //获取最新心跳时间
                        Integer lastHeartBeatTime = deviceInfoMobileWeChatCacheDto.getLastHeartBeatTime();
                        if (lastHeartBeatTime != null) {
                            //判断是否在线
                            if (DateUtil.getNowTime() - lastHeartBeatTime.intValue() < Const.Device.HEART_BEAT_OFF_LINE_TIME.intValue()) {
                                onlineFlag = true;
                            }
                        }
                    }
                }

                //在线，则发送刷新通讯录
                if (onlineFlag) {
                    //发送MQ消息
                    MsgDto<Object> msgDto = new MsgDto<>();
                    msgDto.setContent(null);
                    msgDto.setId(IdWorker.getId());
                    msgDto.setDeviceType(deviceWechatInfo.getRecvmsgType());
                    msgDto.setDeviceUniqueId(deviceWechatInfo.getId());
                    msgDto.setMerId(deviceWechatInfo.getMerId());
                    msgDto.setMsgType(MessageFuncEnum.GET_MAIL_LIST_REQ.getValue());
                    noticeMsgPushProducerService.updateWxContacts(msgDto);
                    //修改机器人更新通讯录时间
                    deviceWechatInfoMapper.updateRefreshWxcontactsTime(deviceWechatInfo.getId(), DateUtil.getNowTime());
                }
            }

            //限制凌晨00:00 到早上08:00点执行
            //开始限制时间（HH:mm）
            String limitTimeStart = "00:00";
            //结束限制时间（HH:mm）
            String limitTimeEnd = "08:00";
            // 获取当前时间
            LocalDateTime now_localDateTime = LocalDateTime.now();
            //判断当前时间是否在自动任务开启时间区间内
            boolean withinTimeInterval = Tools.isWithinTimeInterval(now_localDateTime, LocalTime.parse(limitTimeStart), LocalTime.parse(limitTimeEnd));
            //不在区间内，则跳过
            if (!withinTimeInterval) {
                return;
            }

            //下次查询间隔60秒
            int nextTime = DateUtil.getNowTime();
            //相隔时间=这次时间-上次时间
            int delayTime = nextTime - lastTime;
            //如果间隔时间小于60秒，则线程睡眠，直到一分钟结束
            if (delayTime < 60) {
                try {
                    //睡眠时间=60秒-间隔时间
                    int sleepTime = 60 - delayTime;
                    Thread.sleep(sleepTime * 1000L);
                } catch (Exception e) {
                }
            }
            deviceWechatInfoQuery.setIdStart(idStart);
            deviceWechatInfoList = deviceWechatInfoMapper.findSimpleByList(page, deviceWechatInfoQuery);
        }
    }

    /**
     * 自动刷新企业微信通讯录
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void refreshWxworkContacts() {

        logger.info("-----调用企业微信刷新通讯录线程----");

        Integer reFreshWxcontactsNum = uzaiConsoleSysConfig.getReFreshWxcontactsNum();
        if (reFreshWxcontactsNum == null) {
            reFreshWxcontactsNum = 20;
        }

        //个人微信机器人是否掉线
        DeviceWxworkInfoQuery deviceWxworkInfoQuery = new DeviceWxworkInfoQuery();
        //查询所有机器人
        Page<DeviceWxworkInfo> page = new Page<>();
        page.setCurrent(1);//只查第一页
        page.setSize(reFreshWxcontactsNum); //每页查询20个
        page.addOrder(OrderItem.asc("id"));//默认id升序
        Long idStart = 0L;
        List<DeviceWxworkInfo> deviceWxworkInfoList = deviceWxworkInfoMapper.findSimpleByList(page, deviceWxworkInfoQuery);
        while (deviceWxworkInfoList != null && deviceWxworkInfoList.size() > 0) {
            //上次查询时间（第一次为当前时间）
            int lastTime = DateUtil.getNowTime();
            for (DeviceWxworkInfo deviceWxworkInfo : deviceWxworkInfoList) {

                if (deviceWxworkInfo.getId().longValue() > idStart.longValue()) {
                    idStart = deviceWxworkInfo.getId();
                }

                //限流判断(30秒内判断一次)
                boolean inRateLimit = ratelimitService.inRateLimit("refreshWxworkContacts-" + deviceWxworkInfo.getId(), 1, 30);
                if (!inRateLimit) {
                    //logger.info("{}:inRateLimit false. deviceUniqueId=", deviceAuth.getDeviceUniqueId());
                    continue;
                }

                //在线标志
                boolean onlineFlag_pc = false;     //在线标志
                //从缓存中换取个人微信PC端信息
                Object object_pc = redisTemplate.opsForValue().get(String.format(RedisCacheKeyEnum.DEVICE_INFO_WXWORK.getKey(), deviceWxworkInfo.getId()));
                DeviceInfoWxWorkCacheDto deviceInfoWxWorkCacheDto = JSONObject.parseObject(String.valueOf(object_pc), DeviceInfoWxWorkCacheDto.class);
                //PC端个人微信信息不为空
                if (deviceInfoWxWorkCacheDto != null) {
                    //获取最新心跳时间
                    Integer lastHeartBeatTime = deviceInfoWxWorkCacheDto.getLastHeartBeatTime();
                    if (lastHeartBeatTime != null) {
                        //判断是否刚掉线（心跳时间在5分钟以外，且 少于 15天之内）
                        if (DateUtil.getNowTime() - lastHeartBeatTime.intValue() < Const.Device.HEART_BEAT_OFF_LINE_TIME.intValue()) {
                            onlineFlag_pc = true;
                        }
                    }
                }

                //在线，则发送更新通讯录指令
                if (onlineFlag_pc) {
                    //发送MQ消息
                    MsgDto<Object> msgDto = new MsgDto<>();
                    msgDto.setContent(null);
                    msgDto.setId(IdWorker.getId());
                    msgDto.setDeviceType(DeviceTypeEnum.DT_WORK_WECHAT_VALUE);
                    msgDto.setDeviceUniqueId(deviceWxworkInfo.getMerId());
                    msgDto.setMerId(deviceWxworkInfo.getMerId());
                    msgDto.setMsgType(MessageFuncEnum.GET_MAIL_LIST_REQ.getValue());
                    noticeMsgPushProducerService.updateWxContacts(msgDto);

                    //保存更新通讯录时间
                    deviceWxworkInfoMapper.updateRefreshWxcontactsTime(deviceWxworkInfo.getId(), DateUtil.getNowTime());
                }
            }

            //限制凌晨00:00 到早上08:00点执行
            //开始限制时间（HH:mm）
            String limitTimeStart = "00:00";
            //结束限制时间（HH:mm）
            String limitTimeEnd = "08:00";
            // 获取当前时间
            LocalDateTime now_localDateTime = LocalDateTime.now();
            //判断当前时间是否在自动任务开启时间区间内
            boolean withinTimeInterval = Tools.isWithinTimeInterval(now_localDateTime, LocalTime.parse(limitTimeStart), LocalTime.parse(limitTimeEnd));
            //不在区间内，则跳过
            if (!withinTimeInterval) {
                return;
            }

            //下次查询间隔60秒
            int nextTime = DateUtil.getNowTime();
            //相隔时间=这次时间-上次时间
            int delayTime = nextTime - lastTime;
            //如果间隔时间小于60秒，则线程睡眠，直到一分钟结束
            if (delayTime < 60) {
                try {
                    //睡眠时间=60秒-间隔时间
                    int sleepTime = 60 - delayTime;
                    Thread.sleep(sleepTime * 1000L);
                } catch (Exception e) {
                }
            }
            deviceWxworkInfoQuery.setIdStart(idStart);
            deviceWxworkInfoList = deviceWxworkInfoMapper.findSimpleByList(page, deviceWxworkInfoQuery);
        }
    }

    /**
     * 自动检测僵尸粉任务
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void autoCheckZomBieFanTask() {

        //限流key
        String taskLimitKet = "-autoCheckZomBieFanTask-taskLimitKey-";
        Object object = redisTemplate.opsForValue().get(taskLimitKet);
        if (object != null) {
            return;
        }
        //保存限流key
        redisTemplate.opsForValue().set(taskLimitKet, taskLimitKet, 30, TimeUnit.MINUTES);

        logger.info("-----调用自动检测僵尸粉任务线程----");

        try {
            //查询当前所有开启的自动发圈的配置方案
            int now = DateUtil.getNowTime();

            // 获取当前时间
            LocalDateTime now_localDateTime = LocalDateTime.now();

            String yyyyMMdd = Tools.getDateFormat(new Date(), "yyyy-MM-dd");

            ZombieFanTaskQuery zombieFanTaskQuery = new ZombieFanTaskQuery();
            zombieFanTaskQuery.setStatus(ZombieFanTaskStatusEnum.CHECKING.getId()); //检查中
            //查询所有的自动发圈配置记录
            Page<ZombieFanTask> page = new Page<>();
            page.setCurrent(1);//只查第一页
            page.setSize(10); //每页查询10个
            page.addOrder(OrderItem.asc("id"));//默认id升序
            Long idStart = 0L;
            List<ZombieFanTask> zombieFanTaskList = zombieFanTaskMapper.findByList(page, zombieFanTaskQuery);
            while (zombieFanTaskList != null && zombieFanTaskList.size() > 0) {
                for (ZombieFanTask zombieFanTask : zombieFanTaskList) {
                    try {
                        if (zombieFanTask.getId().longValue() > idStart.longValue()) {
                            idStart = zombieFanTask.getId();
                        }

                        //限流判断
                        String rateLimitKey = "autoCheckZomBieFan-taskId=" + zombieFanTask.getId();
                        boolean inRateLimit = ratelimitService.inRateLimit(rateLimitKey, 1, 30);
                        if (!inRateLimit) {
                            //logger.info("--inRateLimit false. tradeno={}",alipayDetail.getTradeno());
                            continue;
                        }

                        //发送间隔最小时间
                        Integer checkMin = Tools.getInteger(zombieFanTask.getCheckMin());
                        //发送间隔最大时间
                        Integer checkMax = Tools.getInteger(zombieFanTask.getCheckMax());
                        //上次发送时间
                        Integer checkTime = Tools.getInteger(zombieFanTask.getCheckTime());
                        //这次发送时间,默认等于当前时间
                        int sendTimeNew = now;
                        if (checkTime.intValue() != 0) { //已经开始检查任务
                            if (checkTime.intValue() + checkMin.intValue() > now) {//上次发送时间+最小时间间隔，如果还大于当前时间，表示还未轮到，
                                continue;
                            }
                            //获取最小和最大时间的随机数（秒）
                            int random = (int) (Math.random() * (checkMax - checkMin + 1) + checkMin);
                            sendTimeNew = checkTime + random;
                        } else { //如果等于空，则表示第一次发送，默认为0
                            sendTimeNew = now;
                        }

                        //如果发送时间小于当前时间，则默认按照当前时间来发
                        if (sendTimeNew < now) {
                            sendTimeNew = now;
                        }

                        //更新新的检查时间
                        zombieFanTask.setCheckTime(sendTimeNew);
                        zombieFanTask.setUpdateTime(now);

                        //自动检查僵尸粉
                        zombieFanTaskSendInfoService.autoCheckZomBieFanTaskSendInfo(zombieFanTask);

                        //保存成功之后，手动删除限流redisKey
                        redisTemplate.delete(rateLimitKey);
                    } catch (Exception e) {
                        logger.error("--自动检查僵尸粉失败--error={}", e.getMessage());
                    }
                }

                zombieFanTaskQuery.setIdStart(idStart);
                zombieFanTaskList = zombieFanTaskMapper.findByList(page, zombieFanTaskQuery);
            }
        } catch (Exception e) {
            logger.info(e.getMessage());
        } finally {
            //删除限流key
            redisTemplate.delete(taskLimitKet);
        }

    }

    /**
     * 自动清理僵尸粉任务
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void autoDeleteZomBieFanTask() {
        //限流key
        String taskLimitKet = "-autoDeleteZomBieFanTask-taskLimitKey-";
        Object object = redisTemplate.opsForValue().get(taskLimitKet);
        if (object != null) {
            return;
        }
        //保存限流key
        redisTemplate.opsForValue().set(taskLimitKet, taskLimitKet, 30, TimeUnit.MINUTES);

        logger.info("-----调用自动清理僵尸粉任务线程----");

        try {
            //查询当前所有开启的自动发圈的配置方案
            int now = DateUtil.getNowTime();

            ZombieFanTaskQuery zombieFanTaskQuery = new ZombieFanTaskQuery();
            zombieFanTaskQuery.setStatus(ZombieFanTaskStatusEnum.DELETING.getId()); //清粉中
            //查询所有的自动发圈配置记录
            Page<ZombieFanTask> page = new Page<>();
            page.setCurrent(1);//只查第一页
            page.setSize(10); //每页查询10个
            page.addOrder(OrderItem.asc("id"));//默认id升序
            Long idStart = 0L;
            List<ZombieFanTask> zombieFanTaskList = zombieFanTaskMapper.findByList(page, zombieFanTaskQuery);
            while (zombieFanTaskList != null && zombieFanTaskList.size() > 0) {
                for (ZombieFanTask zombieFanTask : zombieFanTaskList) {
                    try {

                        if (zombieFanTask.getId().longValue() > idStart.longValue()) {
                            idStart = zombieFanTask.getId();
                        }

                        //限流判断
                        String rateLimitKey = "autoDeleteZomBieFan-taskId=" + zombieFanTask.getId();
                        boolean inRateLimit = ratelimitService.inRateLimit(rateLimitKey, 1, 30);
                        if (!inRateLimit) {
                            //logger.info("--inRateLimit false. tradeno={}",alipayDetail.getTradeno());
                            continue;
                        }

                        //清理会员状态为0表示第一次清理僵尸粉，需要判断是否开启一次性删除全部的余额和积分都为0的会员僵尸粉
//                    if(Tools.getInteger(zombieFanTask.getDelUserStatus()) == 0){
//                        //删除会员
//                        if(Tools.getInteger(zombieFanTask.getDelUser()).intValue() == 1){ //开启清除0积分0余额的会员
//                            //删除全部的僵尸粉的余额和积分都为0的会员
//                            zombieFanTaskSendInfoService.autoDeleteUser(zombieFanTask);
//                            //修改僵尸粉任务-将清理会员状态为已清除
//                            zombieFanTask.setDelUserStatus(1); //清理会员完成
//                            zombieFanTaskMapper.updateById(zombieFanTask);
//                        }
//                    }

                        //上次清理时间
                        Integer delTime = Tools.getInteger(zombieFanTask.getDelTime());
                        //判断当前时间跟上次处理僵尸粉时间是否是同一天
                        if (!DateUtil.isSameDay(new Date(delTime * 1000L), new Date())) {//不是同一天，则清空当天的清理僵尸粉人数
                            zombieFanTask.setDelDayNum(0);
                            zombieFanTaskMapper.updateById(zombieFanTask);
                        }

                        //今日清理上限已经大于上限，则返回，不清理
                        if (Tools.getInteger(zombieFanTask.getDelDayNum()) >= Tools.getInteger(zombieFanTask.getDelDayLimit())) {
                            continue;
                        }

                        //发送间隔最小时间
                        Integer delMin = Tools.getInteger(zombieFanTask.getDelMin());
                        //发送间隔最大时间
                        Integer delMax = Tools.getInteger(zombieFanTask.getDelMax());
                        //上次清理时间
                        //这次清理时间,默认等于当前时间
                        int delTimeNew = now;
                        if (delTime.intValue() != 0) { //已经开始检查任务
                            if (delTime.intValue() + delMin.intValue() > now) {//上次清理时间+最小时间间隔，如果还大于当前时间，表示还未轮到，
                                continue;
                            }
                            //获取最小和最大时间的随机数（秒）
                            int random = (int) (Math.random() * (delMax - delMin + 1) + delMin);
                            delTimeNew = delTime + random;
                        } else { //如果等于空，则表示第一次发送，默认为0
                            delTimeNew = now;
                        }

                        //如果发送时间小于当前时间，则默认按照当前时间来发
                        if (delTimeNew < now) {
                            delTimeNew = now;
                        }

                        //更新新的清理时间
                        zombieFanTask.setDelTime(delTimeNew);
                        zombieFanTask.setUpdateTime(now);
                        //自动清理僵尸粉
                        zombieFanTaskSendInfoService.autoDeleteZomBieFanTaskSendInfo(zombieFanTask);
                        //保存成功之后，手动删除限流redisKey
                        redisTemplate.delete(rateLimitKey);
                    } catch (Exception e) {
                        logger.error("--自动检查僵尸粉失败--error={}", e.getMessage());
                    }
                }

                zombieFanTaskQuery.setIdStart(idStart);
                zombieFanTaskList = zombieFanTaskMapper.findByList(page, zombieFanTaskQuery);
            }
        } catch (Exception e) {
            logger.info(e.getMessage());
        } finally {
            //删除限流key
            redisTemplate.delete(taskLimitKet);
        }

    }

    /**
     * 自动检测免单商品是否下架
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void autoCheckMdGoodsDrop() {
        //限流key
        String taskLimitKet = "-autoCheckMdGoodsDrop-taskLimitKey-";
        Object object = redisTemplate.opsForValue().get(taskLimitKet);
        if (object != null) {
            return;
        }
        //保存限流key
        redisTemplate.opsForValue().set(taskLimitKet, taskLimitKet, 30, TimeUnit.MINUTES);

        logger.info("-----调用自动检测免单商品是否下架任务线程----");

        try {

            //查询当前所有开启的自动发圈的配置方案
            int now = DateUtil.getNowTime();
            MdActivityQuery mdActivityQuery = new MdActivityQuery();
            mdActivityQuery.setSource(0); //私有商品
            mdActivityQuery.setValidTime(now);
            //查询所有的自动发圈配置记录
            Page<MdActivity> page = new Page<>();
            page.setCurrent(1);//只查第一页
            page.setSize(10); //每页查询10个
            page.addOrder(OrderItem.asc("id"));//默认id升序
            Long idStart = 0L;
            List<MdActivity> mdActivityList = mdActivityMapper.findByList(page, mdActivityQuery);
            while (mdActivityList != null && mdActivityList.size() > 0) {
                for (MdActivity mdActivity : mdActivityList) {
                    try {

                        if (mdActivity.getId().longValue() > idStart.longValue()) {
                            idStart = mdActivity.getId();
                        }

                        //限流判断
                        String rateLimitKey = "autoCheckMdGoodsDrop-taskId=" + mdActivity.getId();
                        boolean inRateLimit = ratelimitService.inRateLimit(rateLimitKey, 1, 30);
                        if (!inRateLimit) {
                            //logger.info("--inRateLimit false. tradeno={}",alipayDetail.getTradeno());
                            continue;
                        }

                        //自动检测免单获得是否有优惠券
                        mdActivityService.autoCheckMdGoodsDrop(mdActivity);

                        //保存成功之后，手动删除限流redisKey
                        redisTemplate.delete(rateLimitKey);
                    } catch (Exception e) {
                        logger.error("--自动检测免单商品是否下架失败--error={}", e.getMessage());
                    }
                }

                mdActivityQuery.setIdStart(idStart);
                mdActivityList = mdActivityMapper.findByList(page, mdActivityQuery);
            }
        } catch (Exception e) {
            logger.info(e.getMessage());
        } finally {
            //删除限流key
            redisTemplate.delete(taskLimitKet);
        }
    }

    /**
     * 自动检测免单商品兑换记录是否过期
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    public void autoCheckMdExchangeExpired() {
        //限流key
        String taskLimitKet = "-autoCheckMdExchangeExpired-taskLimitKey-";
        Object object = redisTemplate.opsForValue().get(taskLimitKet);
        if (object != null) {
            return;
        }
        //保存限流key
        redisTemplate.opsForValue().set(taskLimitKet, taskLimitKet, 30, TimeUnit.MINUTES);

        logger.info("-----调用自动检测免单商品兑换记录是否过期任务线程----");

        try {

            //查询还未有下单的免单兑换记录
            int now = DateUtil.getNowTime();
            MdExchangeQuery mdExchangeQuery = new MdExchangeQuery();
            mdExchangeQuery.setStatus(1); //有效商品
            mdExchangeQuery.setExptime(now); //当前时间
            mdExchangeQuery.setOrdered(0); //未下单
            //查询所有的自动发圈配置记录
            Page<MdExchange> page = new Page<>();
            page.setCurrent(1);//只查第一页
            page.setSize(10); //每页查询10个
            page.addOrder(OrderItem.asc("id"));//默认id升序
            Long idStart = 0L;
            List<MdExchange> mdExchangeList = mdExchangeMapper.findByList(page, mdExchangeQuery);
            while (mdExchangeList != null && mdExchangeList.size() > 0) {
                for (MdExchange mdExchange : mdExchangeList) {
                    try {

                        if (mdExchange.getId().longValue() > idStart.longValue()) {
                            idStart = mdExchange.getId();
                        }

                        //限流判断
                        String rateLimitKey = "autoCheckMdExchangeExpired-taskId=" + mdExchange.getId();
                        boolean inRateLimit = ratelimitService.inRateLimit(rateLimitKey, 1, 30);
                        if (!inRateLimit) {
                            //logger.info("--inRateLimit false. tradeno={}",alipayDetail.getTradeno());
                            continue;
                        }

                        //自动检测免单兑换记录是否已经过期
                        mdExchangeService.autoCheckMdExchangeExpired(mdExchange);

                        //保存成功之后，手动删除限流redisKey
                        redisTemplate.delete(rateLimitKey);
                    } catch (Exception e) {
                        logger.error("--自动检测免单商品兑换记录是否过期失败--error={}", e.getMessage());
                    }
                }

                mdExchangeQuery.setIdStart(idStart);
                mdExchangeList = mdExchangeMapper.findByList(page, mdExchangeQuery);
            }
        } catch (Exception e) {
            logger.info(e.getMessage());
        } finally {
            //删除限流key
            redisTemplate.delete(taskLimitKet);
        }

    }

    /**
     * 快站域名到期发送报警消息
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void kuaizhanDomainExpiredAlarmMsg() {
        //限流key
        String taskLimitKet = "-kuaizhanDomainExpiredAlarmMsg-taskLimitKey-";
        Object object = redisTemplate.opsForValue().get(taskLimitKet);
        if (object != null) {
            return;
        }
        //保存限流key
        redisTemplate.opsForValue().set(taskLimitKet, taskLimitKet, 30, TimeUnit.MINUTES);

        try {

            logger.info("-----调用自动检测快站域名到期发送报警消息线程----");
            SysDomainQuery sysDomainQuery = new SysDomainQuery();
            sysDomainQuery.setType(1); //快站域名
            //查询所有的自动发圈配置记录
            Page<SysDomain> page = new Page<>();
            page.setCurrent(1);//只查第一页
            page.setSize(10); //每页查询10个
            page.addOrder(OrderItem.asc("id"));//默认id升序
            Long idStart = 0L;
            List<SysDomain> sysDomainList = sysDomainMapper.findByList(page, sysDomainQuery);
            while (sysDomainList != null && sysDomainList.size() > 0) {
                for (SysDomain sysDomain : sysDomainList) {
                    try {

                        if (sysDomain.getId().longValue() > idStart.longValue()) {
                            idStart = sysDomain.getId();
                        }

                        //限流判断
                        String rateLimitKey = "kuaizhanDomainExpiredAlarmMsg-taskId=" + sysDomain.getId();
                        boolean inRateLimit = ratelimitService.inRateLimit(rateLimitKey, 1, 30);
                        if (!inRateLimit) {
                            //logger.info("--inRateLimit false. tradeno={}",alipayDetail.getTradeno());
                            continue;
                        }

                        //从缓存种获取事件报警监控
                        MerBaseConfig merBaseConfig = merBaseConfigMapper.selectByMerId(sysDomain.getMerId(), MerConfigKeyEnum.ALARM_EVENT_CONFIG.getValue());
                        if (merBaseConfig != null && StringUtils.isNotBlank(merBaseConfig.getVal())) {
                            AlarmEventConfigVo alarmEventConfigVo = JSONObject.parseObject(merBaseConfig.getVal(), AlarmEventConfigVo.class);
                            //判断快站域名到期报警开关是否开启
                            if (alarmEventConfigVo != null && Tools.getInteger(alarmEventConfigVo.getKzDomainExpired()).intValue() == 1) {
                                //唯品会报警提前时间(天)
                                Integer kzDomainExpired = Tools.getInteger(alarmEventConfigVo.getKzDomainExpiredTime());
                                //查询快站域名，检查到期天数
                                GetSiteInfoVo getSiteInfoVo = kuaiZhanService.getSiteInfo(sysDomain.getSiteId());
                                if (getSiteInfoVo != null) {
                                    //站点套餐剩余天数
                                    int packageRemainingDays = Tools.getInteger(getSiteInfoVo.getPackageRemainingDays()).intValue();
                                    if (packageRemainingDays <= kzDomainExpired && packageRemainingDays > 0) {
                                        Merchant merchant = merchantMapper.selectById(sysDomain.getMerId());
                                        if (merchant != null) {
                                            //发送其他异常提醒
                                            AlarmMsgFeignDto alarmMsgFeignDto = new AlarmMsgFeignDto();
                                            alarmMsgFeignDto.setMerId(merchant.getId());
                                            alarmMsgFeignDto.setType(SysMsgTypeEnum.OTHER_EXCEPTION.getValue()); //其他异常提醒
                                            //消息
                                            JSONObject ext = new JSONObject();
                                            StringBuilder content = new StringBuilder();
                                            content.append("快站域名将要到期;\n站点id为：" + sysDomain.getSiteId() + ";\n域名为：" + sysDomain.getSiteDomain());
                                            //当前操作员
                                            ext.put("content", content.toString());
                                            ext.put("phone", merchant.getMobile());
                                            ext.put("errorcode", content.toString());
                                            alarmMsgFeignDto.setExt(ext.toJSONString());
//                                            UzaiRespVo uzaiRespVo = uzaiBroadcastFeignService.sysMsgPush(alarmMsgFeignDto);
//                                            logger.info("---快站域名到期发送异常消息-para={}, result={}", JSONObject.toJSONString(alarmMsgFeignDto), JSONObject.toJSONString(uzaiRespVo));

                                            //2024-01-09修改成直接发送MQ
                                            noticeMsgPushProducerService.sendSysAlarmMsgAsync(alarmMsgFeignDto);
                                        }
                                    }
                                }
                            }
                        }

                        //保存成功之后，手动删除限流redisKey
                        redisTemplate.delete(rateLimitKey);
                    } catch (Exception e) {
                        logger.error("--自动检测快站域名到期发送报警消息--error={}", e.getMessage());
                    }
                }

                sysDomainQuery.setIdStart(idStart);
                sysDomainList = sysDomainMapper.findByList(page, sysDomainQuery);
            }
        } catch (Exception e) {
            logger.info(e.getMessage());
        } finally {
            //删除限流key
            redisTemplate.delete(taskLimitKet);
        }
    }

    /**
     * 自动检测免单商品是否下架
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void autoOrderPull() {
        logger.info("-----调用订单下载任务线程----");
        OrderPullQuery orderPullQuery = new OrderPullQuery();
        //查询当前所有的订单拉取记录
        Page<OrderPull> page = new Page<>();
        page.setCurrent(1);//只查第一页
        page.setSize(10); //每页查询10个
        page.addOrder(OrderItem.asc("id"));//默认id升序
        Long idStart = 0L;
        List<OrderPull> orderPullList = orderPullMapper.findByList(page, orderPullQuery);
        if (orderPullList != null && orderPullList.size() > 0) {
            for (OrderPull orderPull : orderPullList) {
                try {
                    //限流判断
                    String rateLimitKey = "autoOrderPull-taskId=" + orderPull.getId();
                    boolean inRateLimit = ratelimitService.inRateLimit(rateLimitKey, 1, 30);
                    if (!inRateLimit) {
                        //logger.info("--inRateLimit false. tradeno={}",alipayDetail.getTradeno());
                        continue;
                    }

                    //订单下载
                    orderPullService.autoOrderPull(orderPull);

                    //保存成功之后，手动删除限流redisKey
                    redisTemplate.delete(rateLimitKey);
                } catch (Exception e) {
                    logger.error("--自动检测免单商品是否下架失败--error={}", e.getMessage());
                }
            }
        }
    }

    /**
     * 群内自动添加好友任务
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void autoWxqAddFriendTask() {
        //限流key
        String taskLimitKet = "-autoWxqAddFriendTask-taskLimitKey-";
        Object object = redisTemplate.opsForValue().get(taskLimitKet);
        if (object != null) {
            return;
        }
        //保存限流key
        redisTemplate.opsForValue().set(taskLimitKet, taskLimitKet, 30, TimeUnit.MINUTES);

        logger.info("-----调用自动微信群添加好友任务线程----");

        try {

            //查询当前所有开启的自动发圈的配置方案
            int now = DateUtil.getNowTime();

            // 获取当前时间
            LocalDateTime now_localDateTime = LocalDateTime.now();

            WxqAddFriendTaskQuery wxqAddFriendTaskQuery = new WxqAddFriendTaskQuery();
            wxqAddFriendTaskQuery.setStatus(WxqAddFriendTaskStatusEnum.ADDING.getId()); //进行中
            //查询所有的自动发圈配置记录
            Page<WxqAddFriendTask> page = new Page<>();
            page.setCurrent(1);//只查第一页
            page.setSize(10); //每页查询10个
            page.addOrder(OrderItem.asc("id"));//默认id升序
            Long idStart = 0L;
            List<WxqAddFriendTask> wxqAddFriendTaskList = wxqAddFriendTaskMapper.findByList(page, wxqAddFriendTaskQuery);
            while (wxqAddFriendTaskList != null && wxqAddFriendTaskList.size() > 0) {
                for (WxqAddFriendTask wxqAddFriendTask : wxqAddFriendTaskList) {
                    try {

                        if (wxqAddFriendTask.getId().longValue() > idStart.longValue()) {
                            idStart = wxqAddFriendTask.getId();
                        }

                        //限流判断
                        String rateLimitKey = "autoWxqAddFriendTask-taskId=" + wxqAddFriendTask.getId();
                        boolean inRateLimit = ratelimitService.inRateLimit(rateLimitKey, 1, 30);
                        if (!inRateLimit) {
                            //logger.info("--inRateLimit false. tradeno={}",alipayDetail.getTradeno());
                            continue;
                        }

                        //上次添加时间
                        Integer addTime = Tools.getInteger(wxqAddFriendTask.getAddTime());
                        //判断当前时间跟上次处理僵尸粉时间是否是同一天
                        if (!DateUtil.isSameDay(new Date(addTime * 1000L), new Date())) {//不是同一天，则更新每天允许添加的随机数和清空当天的添加好友人数
                            //每天添加下限
                            Integer addDayMin = Tools.getInteger(wxqAddFriendTask.getAddDayMin());
                            //每天添加上限
                            Integer addDayMax = Tools.getInteger(wxqAddFriendTask.getAddDayMax());
                            //获取每天最小和每天最大添加数的随机数
                            int addDayRandom = (int) (Math.random() * (addDayMax - addDayMin + 1) + addDayMin);
                            wxqAddFriendTask.setAddDayLimit(addDayRandom); //更新每天允许添加的随机数
                            wxqAddFriendTask.setAddDayNum(0);               //则清空当天的添加好友人数
                            wxqAddFriendTaskMapper.updateById(wxqAddFriendTask);
                        }

                        //今日添加上限已经大于上限，则返回，不添加
                        if (Tools.getInteger(wxqAddFriendTask.getAddDayNum()) >= Tools.getInteger(wxqAddFriendTask.getAddDayLimit())) {
                            continue;
                        }

                        //开始限制时间（HH:mm）
                        String limitTimeStart = wxqAddFriendTask.getLimitTimeStart();
                        //结束限制时间（HH:mm）
                        String limitTimeEnd = wxqAddFriendTask.getLimitTimeEnd();
                        //限制时间不为空，才验证
                        if (StringUtils.isNotBlank(limitTimeStart) && StringUtils.isNotBlank(limitTimeEnd)) {
                            //判断当前时间是否在自动任务开启时间区间内
                            boolean withinTimeInterval = Tools.isWithinTimeInterval(now_localDateTime, LocalTime.parse(limitTimeStart), LocalTime.parse(limitTimeEnd));
                            //在区间内，则跳过(禁止时间段)
                            if (withinTimeInterval) {
                                continue;
                            }
                        }

                        //添加好友发送请求间隔最小时间
                        Integer rateMin = Tools.getInteger(wxqAddFriendTask.getRateMin());
                        //添加好友发送间隔最大时间
                        Integer rateMax = Tools.getInteger(wxqAddFriendTask.getRateMax());
                        //这次添加时间,默认等于当前时间
                        int addTimeNew = now;
                        if (addTime.intValue() != 0) { //已经开始进行任务
                            if (addTime.intValue() + rateMin.intValue() * 60 > now) {//上次清理时间+最小时间间隔，如果还大于当前时间，表示还未轮到，
                                continue;
                            }
                            //获取最小和最大时间的随机数（秒）
                            int rateRandom = (int) (Math.random() * (rateMax - rateMin + 1) + rateMin);
                            addTimeNew = addTime + rateRandom * 60;
                        } else { //如果等于空，则表示第一次发送，默认为0
                            addTimeNew = now;
                        }

                        //如果发送时间小于当前时间，则默认按照当前时间来发
                        if (addTimeNew < now) {
                            addTimeNew = now;
                        }

                        //更新新的清理时间
                        wxqAddFriendTask.setAddTime(addTimeNew);
                        wxqAddFriendTask.setUpdateTime(now);
                        //自动发送微信群好友添加申请
                        wxqAddFriendTaskAddInfoService.autoSendWxqAddFriendTaskAddInfo(wxqAddFriendTask);
                        //保存成功之后，手动删除限流redisKey
                        redisTemplate.delete(rateLimitKey);
                    } catch (Exception e) {
                        logger.error("--自动微信群添加好友失败--error={}", e.getMessage());
                    }
                }

                wxqAddFriendTaskQuery.setIdStart(idStart);
                wxqAddFriendTaskList = wxqAddFriendTaskMapper.findByList(page, wxqAddFriendTaskQuery);
            }
        } catch (Exception e) {
            logger.info(e.getMessage());
        } finally {
            //删除限流key
            redisTemplate.delete(taskLimitKet);
        }
    }

    /**
     * 封装SOP任务
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void autoSopTask() {
        logger.info("-----调用封装SOP任务线程----");
        //查询当前所有开启的自动发圈的配置方案
        int now = DateUtil.getNowTime();
        SopTaskQuery sopTaskQuery = new SopTaskQuery();
        List statList = Lists.newArrayList(SopTaskStatusEnum.ADDING.getId(), SopTaskStatusEnum.COMPLETED.getId());
        sopTaskQuery.setStatusList(statList); //进行中
        //查询所有的自动发圈配置记录
        Page<SopTask> page = new Page<>();
        page.setCurrent(1);//只查第一页
        page.setSize(10); //每页查询10个
        page.addOrder(OrderItem.asc("id"));//默认id升序
        Long idStart = 0L;
        List<SopTask> sopTaskList = sopTaskMapper.findByList(page, sopTaskQuery);
        while (sopTaskList != null && sopTaskList.size() > 0) {
            for (SopTask sopTask : sopTaskList) {
                try {
                    if (sopTask.getId().longValue() > idStart.longValue()) {
                        idStart = sopTask.getId();
                    }
                    //限流判断
                    String rateLimitKey = "autoSopTask-taskId=" + sopTask.getId();
                    boolean inRateLimit = ratelimitService.inRateLimit(rateLimitKey, 1, 30);
                    if (!inRateLimit) {
                        //logger.info("--inRateLimit false. tradeno={}",alipayDetail.getTradeno());
                        continue;
                    }

                    //查询条件
                    if (StringUtils.isNotBlank(sopTask.getQueryPara())) {
                        SopTaskQueryParaVo sopTaskQueryParaVo = JSONObject.parseObject(sopTask.getQueryPara(), SopTaskQueryParaVo.class);
                        if (sopTaskQueryParaVo != null) {
                            Integer queryTime = Tools.getInteger(sopTaskQueryParaVo.getQueryTime());
                            if (queryTime == 0) { //查询天数等于0。表示查询从未下单的会员，这种情况只在建立任务时初始化，之后不在封装明细
                                continue;
                            }
                        }
                    }

                    //循环机器人，依次建立每个机器人的添加好友任务
                    if (sopTask.getType().intValue() == 1) { //查券未下单
                        //sopTaskSyncService.addSopTaskByQueryNoOrder(sopTask);
                    } else if (sopTask.getType().intValue() == 2) { //未下单
                        sopTaskSyncService.addSopTaskByNoOrder(sopTask);
                    } else if (sopTask.getType().intValue() == 3) { //红包未领取
                        sopTaskSyncService.addSopTaskByRedNoReceive(sopTask);
                    } else {
                        throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "类型输入有误");
                    }

                    //保存成功之后，手动删除限流redisKey
                    redisTemplate.delete(rateLimitKey);
                } catch (Exception e) {
                    logger.error("--自动封装SOP任务失败--error={}", e.getMessage());
                }
            }
            sopTaskQuery.setIdStart(idStart);
            sopTaskList = sopTaskMapper.findByList(page, sopTaskQuery);
        }
    }

    /**
     * SOP任务
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void autoSopTaskAddInfo() {
        //限流key
        String taskLimitKet = "-autoSopTaskAddInfo-taskLimitKey-";
        Object object = redisTemplate.opsForValue().get(taskLimitKet);
        if (object != null) {
            return;
        }
        //保存限流key
        redisTemplate.opsForValue().set(taskLimitKet, taskLimitKet, 30, TimeUnit.MINUTES);

        logger.info("-----调用清理SOP任务明细线程----");

        try {

            //查询当前所有开启的自动发圈的配置方案
            int now = DateUtil.getNowTime();

            // 获取当前时间
            LocalDateTime now_localDateTime = LocalDateTime.now();

            SopTaskQuery sopTaskQuery = new SopTaskQuery();
            List statList = Lists.newArrayList(SopTaskStatusEnum.ADDING.getId(), SopTaskStatusEnum.COMPLETED.getId());
            sopTaskQuery.setStatusList(statList); //进行中
            //查询所有的自动发圈配置记录
            Page<SopTask> page = new Page<>();
            page.setCurrent(1);//只查第一页
            page.setSize(10); //每页查询10个
            page.addOrder(OrderItem.asc("id"));//默认id升序
            Long idStart = 0L;
            List<SopTask> sopTaskList = sopTaskMapper.findByList(page, sopTaskQuery);
            while (sopTaskList != null && sopTaskList.size() > 0) {
                for (SopTask sopTask : sopTaskList) {
                    try {

                        if (sopTask.getId().longValue() > idStart.longValue()) {
                            idStart = sopTask.getId();
                        }

                        //限流判断
                        String rateLimitKey = "autoSopTaskAddInfo-taskId=" + sopTask.getId();
                        boolean inRateLimit = ratelimitService.inRateLimit(rateLimitKey, 1, 30);
                        if (!inRateLimit) {
                            //logger.info("--inRateLimit false. tradeno={}",alipayDetail.getTradeno());
                            continue;
                        }

                        //判断是否终止该任务
                        Integer exptime = Tools.getInteger(sopTask.getExptime());
                        //有终止时间，且终于时间小于当前时间,表示该任务需要终止
                        if (exptime.intValue() != 0 && exptime.intValue() <= now) {
                            sopTask.setStatus(SopTaskStatusEnum.STOP.getId());
                            sopTask.setUpdateTime(now);
                            sopTaskMapper.updateById(sopTask);
                            continue;
                        }

                        //上次添加时间
                        Integer addTime = Tools.getInteger(sopTask.getAddTime());

                        //进行中的任务，则处理明细，如果是完成中的任务，则需要判断是否重新开启任务进行中
                        if (sopTask.getStatus().intValue() == SopTaskStatusEnum.ADDING.getId()) {
                            //开始限制时间（HH:mm）
                            String limitTimeStart = sopTask.getLimitTimeStart();
                            //结束限制时间（HH:mm）
                            String limitTimeEnd = sopTask.getLimitTimeEnd();
                            //限制时间不为空，才验证
                            if (StringUtils.isNotBlank(limitTimeStart) && StringUtils.isNotBlank(limitTimeEnd)) {
                                //判断当前时间是否在自动任务禁止时间区间内
                                boolean withinTimeInterval = Tools.isWithinTimeInterval(now_localDateTime, LocalTime.parse(limitTimeStart), LocalTime.parse(limitTimeEnd));
                                //在区间内，则跳过(禁止时间段)
                                if (withinTimeInterval) {
                                    continue;
                                }
                            }

                            //添加好友发送请求间隔最小时间
                            Integer rateMin = Tools.getInteger(sopTask.getRateMin());
                            //添加好友发送间隔最大时间
                            Integer rateMax = Tools.getInteger(sopTask.getRateMax());
                            //这次添加时间,默认等于当前时间
                            int addTimeNew = now;
                            if (addTime.intValue() != 0) { //已经开始进行任务
                                if (addTime.intValue() + rateMin.intValue() > now) {//上次清理时间+最小时间间隔，如果还大于当前时间，表示还未轮到，
                                    continue;
                                }
                                //获取最小和最大时间的随机数（秒）
                                int rateRandom = (int) (Math.random() * (rateMax - rateMin + 1) + rateMin);
                                addTimeNew = addTime + rateRandom;
                            } else { //如果等于空，则表示第一次发送，默认为0
                                addTimeNew = now;
                            }

                            //如果发送时间小于当前时间，则默认按照当前时间来发
                            if (addTimeNew < now) {
                                addTimeNew = now;
                            }

                            //更新新的清理时间
                            sopTask.setAddTime(addTimeNew);
                            sopTask.setUpdateTime(now);
                            //自动发送微信群好友添加申请
                            sopTaskAddInfoService.autoSendSopTaskAddInfo(sopTask);
                        }

                        //保存成功之后，手动删除限流redisKey
                        redisTemplate.delete(rateLimitKey);
                    } catch (Exception e) {
                        logger.error("--自动清理SOP任务明细失败--error={}", e.getMessage());
                    }
                }

                sopTaskQuery.setIdStart(idStart);
                sopTaskList = sopTaskMapper.findByList(page, sopTaskQuery);
            }
        } catch (Exception e) {
            logger.info(e.getMessage());
        } finally {
            //删除限流key
            redisTemplate.delete(taskLimitKet);
        }
    }

    /**
     * 个人微信机器人移动端话费自动查询
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void autoSendDeviceWechatPhoneBalTask() {
        logger.info("-----调用个人微信设备移动端发送话费查询线程----");

        int now = DateUtil.getNowTime();

        //个人微信机器人是否掉线
        DeviceWechatInfoQuery deviceWechatInfoQuery = new DeviceWechatInfoQuery();

        //查询所有机器人
        Page<DeviceWechatInfo> page = new Page<>();
        page.setCurrent(1);//只查第一页
        page.setSize(10); //每页查询20个
        page.addOrder(OrderItem.asc("id"));//默认id升序
        Long idStart = 0L;

        List<DeviceWechatInfo> deviceWechatInfoList = deviceWechatInfoMapper.findSimpleByList(page, deviceWechatInfoQuery);

        //判断当天生效时间范围
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String day = sdf.format(new Date());

        while (deviceWechatInfoList != null && deviceWechatInfoList.size() > 0) {
            for (DeviceWechatInfo deviceWechatInfo : deviceWechatInfoList) {
                if (deviceWechatInfo.getId().longValue() > idStart.longValue()) {
                    idStart = deviceWechatInfo.getId();
                }

                //限流判断(30秒内判断一次)
                boolean inRateLimit = ratelimitService.inRateLimit("autoSendDeviceWechatPhoneBalTask-" + deviceWechatInfo.getId(), 1, 30);
                if (!inRateLimit) {
                    //logger.info("{}:inRateLimit false. deviceUniqueId=", deviceAuth.getDeviceUniqueId());
                    continue;
                }

                //是否配置了报警规则
                if (deviceWechatInfo.getAlarmRuleId() != null) {
                    AlarmRule alarmRule = alarmRuleMapper.selectById(deviceWechatInfo.getAlarmRuleId(), deviceWechatInfo.getMerId());
                    if (alarmRule != null && Tools.getInteger(alarmRule.getStatus()).intValue() == 1) { //报警规则开启才判断
                        //有效开始时间
                        String startTimeStr = day + " " + alarmRule.getStartTime() + ":00";
                        int startTime = DateUtil.getStrTime(startTimeStr);
                        //有效结束
                        String endTimeStr = day + " " + alarmRule.getEndTime() + ":00";
                        int endTime = DateUtil.getStrTime(endTimeStr);

                        //验证当前时间是否在有效时间之内，在之内才触发报警消息
                        //if(now >= startTime && now <= endTime){

                        //设备话费余额报警
                        boolean phoneBalFlag = false;      //话费余额不足标志

                        //判断手机端在线，还是电脑端在线
                        int recvmsgType = Tools.getInteger(deviceWechatInfo.getRecvmsgType()).intValue();
                        if (recvmsgType == DeviceTypeEnum.DT_ANDROID_WECHAT_VALUE) {//手机端在线
                            //判断是否有报警规则-磁盘使用率报警/话费余额报警
                            if (StringUtils.isNotBlank(alarmRule.getRuleInfo())) {
                                List<AlarmRuleContentVo> alarmRuleContentList = JSONObject.parseArray(alarmRule.getRuleInfo(), AlarmRuleContentVo.class);
                                if (alarmRuleContentList != null && alarmRuleContentList.size() > 0) {
                                    for (AlarmRuleContentVo alarmRuleContentVo : alarmRuleContentList) {
                                        if ("device".equals(alarmRuleContentVo.getSystemType())) { //设备
                                            //话费余额
                                            if ("phonebal".equals(alarmRuleContentVo.getAlarmType())) {
                                                //报警规则设置的报警值
                                                Integer averageRate = alarmRuleContentVo.getAverageRate();
                                                if (averageRate != null) { //开启了话费余额
                                                    phoneBalFlag = true;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        //是否开启话费余额报警，如果开启了，则需要发送请求查询话费余额接口
                        if (phoneBalFlag) {
                            if (StringUtils.isNotBlank(deviceWechatInfo.getMobile()) && deviceWechatInfo.getMobiletype() != null) { //机器人必须有手机号才能发送查询话费
                                //一天只查询一次（判断上次发送时间是否跟当前时间是否是同一天）
                                Integer sendTime = Tools.getInteger(deviceWechatInfo.getSendTime());
                                if (sendTime == 0 || !(DateUtil.isSameDay(new Date(sendTime * 1000L), new Date()))) {//一次都没发送过或者不是同一天，则发送请求话费余额查询
                                    //发送请求查询话费余额指令
                                    MsgDto<SendSmsReqProtoc> msgDto = new MsgDto<>();
                                    SendSmsReqProtoc sendSmsReqProtoc = new SendSmsReqProtoc();
                                    if (deviceWechatInfo.getMobiletype().intValue() == 0) { //电信
                                        sendSmsReqProtoc.setSendMobile("10001");
                                        sendSmsReqProtoc.setContent("101");
                                    } else if (deviceWechatInfo.getMobiletype().intValue() == 1) {//移动
                                        sendSmsReqProtoc.setSendMobile("10086");
                                        sendSmsReqProtoc.setContent("101");
                                    } else if (deviceWechatInfo.getMobiletype().intValue() == 2) {//联通
                                        sendSmsReqProtoc.setSendMobile("10010");
                                        sendSmsReqProtoc.setContent("话费查询");
                                    }
                                    msgDto.setContent(sendSmsReqProtoc);
                                    msgDto.setId(IdWorker.getId());
                                    msgDto.setDeviceType(deviceWechatInfo.getRecvmsgType());
                                    msgDto.setDeviceUniqueId(deviceWechatInfo.getId());
                                    msgDto.setMerId(deviceWechatInfo.getMerId());
                                    msgDto.setMsgType(MessageFuncEnum.SEND_SMS.getValue());
                                    noticeMsgPushProducerService.sendQueryPhoneBal(msgDto);

                                    //修改此机器人的发送时间
                                    deviceWechatInfo.setSendTime(now);
                                    deviceWechatInfoMapper.updateById(deviceWechatInfo);
                                }
                            }
                        }
                        //}
                    }
                }
            }

            deviceWechatInfoQuery.setIdStart(idStart);
            deviceWechatInfoList = deviceWechatInfoMapper.findSimpleByList(page, deviceWechatInfoQuery);
        }
    }

    /**
     * 自动检查小程序团购订单30分钟未支付自动过期线程
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void autoCheckMiniOrderSync() {
        //限流key
        String taskLimitKet = "-autoCheckMiniOrderSync-taskLimitKey-";
        Object object = redisTemplate.opsForValue().get(taskLimitKet);
        if (object != null) {
            return;
        }
        //保存限流key
        redisTemplate.opsForValue().set(taskLimitKet, taskLimitKet, 30, TimeUnit.MINUTES);

        logger.info("-----自动检查小程序团购订单30分钟未支付自动过期线程----");

        try {
            int now = DateUtil.getNowTime();

            //查询30分钟之前下单未支付的订单
            int invalidTime = now - 30 * 60;
            MiniOrderQuery miniOrderQuery = new MiniOrderQuery();
            miniOrderQuery.setStatus(1);     //待付款状态
            miniOrderQuery.setDelStatus(0);   //未删除
            miniOrderQuery.setCreateTimeEnd(invalidTime); //30分钟之前未支付的订单
            //查询所有机器人
            Page<MiniOrder> page = new Page<>();
            page.setCurrent(1);//只查第一页
            page.setSize(10); //每页查询10个
            page.addOrder(OrderItem.asc("id"));//默认id升序
            Long idStart = 0L;

            List<MiniOrder> miniOrderList = miniOrderMapper.findByList(page, miniOrderQuery);

            //判断当天生效时间范围
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String day = sdf.format(new Date());

            while (miniOrderList != null && miniOrderList.size() > 0) {
                for (MiniOrder miniOrder : miniOrderList) {
                    if (miniOrder.getId().longValue() > idStart.longValue()) {
                        idStart = miniOrder.getId();
                    }

                    //限流判断(30秒内判断一次)
                    boolean inRateLimit = ratelimitService.inRateLimit("autoCheckMiniOrderSync-" + miniOrder.getId(), 1, 30);
                    if (!inRateLimit) {
                        //logger.info("{}:inRateLimit false. deviceUniqueId=", deviceAuth.getDeviceUniqueId());
                        continue;
                    }

                    if (miniOrder.getCreateTime() > invalidTime) {
                        continue;
                    }

                    miniOrder.setStatus(MiniOrderStatus.CANCEL.getCode());
                    miniOrder.setUpdateTime(now);
                    miniOrderMapper.updateStatus(miniOrder);
                }

                miniOrderQuery.setIdStart(idStart);
                miniOrderList = miniOrderMapper.findByList(page, miniOrderQuery);
            }
        } catch (Exception e) {
            logger.info(e.getMessage());
        } finally {
            //删除限流key
            redisTemplate.delete(taskLimitKet);
        }
    }

    /**
     * 刷新第三方平台托管微信小程序授权刷新
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void refreshMiniComponentAuthSync() {
        //限流key
        String taskLimitKet = "-refreshMiniComponentAuthSync-taskLimitKey-";
        Object object = redisTemplate.opsForValue().get(taskLimitKet);
        if (object != null) {
            return;
        }
        //保存限流key
        redisTemplate.opsForValue().set(taskLimitKet, taskLimitKet, 30, TimeUnit.MINUTES);

        logger.info("-----自动刷新微信第三方平台刷新小程序授权线程----");

        try {

            int now = DateUtil.getNowTime();

            //查询30分钟之前下单未支付的订单
            MiniComponentAuthQuery miniComponentAuthQuery = new MiniComponentAuthQuery();
            miniComponentAuthQuery.setComponentAppid(uzaiConsoleSysConfig.getMiniComponentAppid());     //第三方平台appid
            //查询所有机器人
            Page<MiniComponentAuth> page = new Page<>();
            page.setCurrent(1);//只查第一页
            page.setSize(10); //每页查询10个
            page.addOrder(OrderItem.asc("id"));//默认id升序
            Long idStart = 0L;

            List<MiniComponentAuth> miniComponentAuthList = miniComponentAuthMapper.findByList(page, miniComponentAuthQuery);

            while (miniComponentAuthList != null && miniComponentAuthList.size() > 0) {
                for (MiniComponentAuth miniComponentAuth : miniComponentAuthList) {
                    if (miniComponentAuth.getId().longValue() > idStart.longValue()) {
                        idStart = miniComponentAuth.getId();
                    }

                    //限流判断(30秒内判断一次)
                    boolean inRateLimit = ratelimitService.inRateLimit("refreshMiniComponentAuthSync-" + miniComponentAuth.getId(), 1, 30);
                    if (!inRateLimit) {
                        //logger.info("{}:inRateLimit false. deviceUniqueId=", deviceAuth.getDeviceUniqueId());
                        continue;
                    }

                    //只刷新90分钟之前的授权
                    if (miniComponentAuth.getAuthTime() > now - 90 * 60) {
                        continue;
                    }

                    //获取第三方授权信息
                    String component_access_token = miniOptService.getComponentAccessToken();
                    AuthorizerAccessToken authorizerAccessToken = miniOptService.getAuthorizerAccessToken(component_access_token, miniComponentAuth.getComponentAppid(), miniComponentAuth.getAuthorizerAppid(), miniComponentAuth.getAuthorizerRefreshToken());
                    if (authorizerAccessToken != null) {
                        miniComponentAuth.setExpiresIn(authorizerAccessToken.getExpires_in());
                        miniComponentAuth.setAuthorizerRefreshToken(authorizerAccessToken.getAuthorizer_refresh_token());
                        miniComponentAuth.setAuthorizerAccessToken(authorizerAccessToken.getAuthorizer_access_token());
                        miniComponentAuth.setAuthTime(now);
                        miniComponentAuth.setUpdateTime(now);
                        miniComponentAuthMapper.updateById(miniComponentAuth);
                    }
                }

                miniComponentAuthQuery.setIdStart(idStart);
                miniComponentAuthList = miniComponentAuthMapper.findByList(page, miniComponentAuthQuery);
            }
        } catch (Exception e) {
            logger.info(e.getMessage());
        } finally {
            //删除限流key
            redisTemplate.delete(taskLimitKet);
        }
    }

    /**
     * 自动刷新微信群通讯录任务
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void autoWxqContactRefresh() {
        logger.info("-----调用自动刷新微信群通讯录任务线程----");

        //允许执行总数
        Integer reFreshWxcontactsNum = uzaiConsoleSysConfig.getReFreshWxcontactsNum();
        if (reFreshWxcontactsNum == null) {
            reFreshWxcontactsNum = 10; //默认10个
        }

        WxqContactRefreshQuery wxqContactRefreshQuery_ing = new WxqContactRefreshQuery();
        wxqContactRefreshQuery_ing.setStatus(1); //查询进行中的任务个数
        Integer count_ing = Tools.getInteger(wxqContactRefreshMapper.findCount(wxqContactRefreshQuery_ing));
        if (count_ing >= reFreshWxcontactsNum) { //最多只允许有10个进行中的任务刷新
            return;
        }

        int size = reFreshWxcontactsNum - count_ing; //保证进行中的总数固定，故本次执行个数为允许总数减去正在运行的总数
        //查询当前所有的订单拉取记录
        WxqContactRefreshQuery wxqContactRefreshQuery_notstart = new WxqContactRefreshQuery();
        wxqContactRefreshQuery_notstart.setStatus(0);
        Page<WxqContactRefresh> page = new Page<>();
        page.setCurrent(1);//只查第一页
        page.setSize(size); //每页查询数
        page.addOrder(OrderItem.asc("id"));//默认id升序
        Long idStart = 0L;
        List<WxqContactRefresh> wxqContactRefreshList = wxqContactRefreshMapper.findByList(page, wxqContactRefreshQuery_notstart);
        if (wxqContactRefreshList != null && wxqContactRefreshList.size() > 0) {
            for (WxqContactRefresh wxqContactRefresh : wxqContactRefreshList) {
                try {
                    //限流判断
                    String rateLimitKey = "autoWxqContactRefresh-taskId=" + wxqContactRefresh.getId();
                    boolean inRateLimit = ratelimitService.inRateLimit(rateLimitKey, 1, 10);
                    if (!inRateLimit) {
                        //logger.info("--inRateLimit false. tradeno={}",alipayDetail.getTradeno());
                        continue;
                    }
                    //刷新通讯录
                    wxqContactRefreshService.autoWxqContactRefresh(wxqContactRefresh);

                    //保存成功之后，手动删除限流redisKey
                    redisTemplate.delete(rateLimitKey);
                } catch (Exception e) {
                    logger.error("--自动刷新微信群通讯录任务失败--error={}", e.getMessage());
                }
            }
        }
    }

    /**
     * 自动处理被动僵尸粉任务
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void autoZombieFanPassiveTask() {

        //限流key
        String taskLimitKet = "-autoZombieFanPassiveTask-taskLimitKey-";
        Object object = redisTemplate.opsForValue().get(taskLimitKet);
        if (object != null) {
            return;
        }
        //保存限流key
        redisTemplate.opsForValue().set(taskLimitKet, taskLimitKet, 30, TimeUnit.MINUTES);

        logger.info("-----调用自动处理被动僵尸粉任务--xxlJob start--");

        try {
            //查询当前所有开启的自动发圈的配置方案
            int now = DateUtil.getNowTime();

            // 获取当前时间
            LocalDateTime now_localDateTime = LocalDateTime.now();

            String yyyyMMdd = Tools.getDateFormat(new Date(), "yyyy-MM-dd");

            ZombieFanPassiveTaskQuery zombieFanPassiveTaskQuery = new ZombieFanPassiveTaskQuery();

            //查询所有的自动发圈配置记录
            Page<ZombieFanPassiveTask> page = new Page<>();
            page.setCurrent(1);//只查第一页
            page.setSize(10); //每页查询10个
            page.addOrder(OrderItem.asc("id"));//默认id升序
            Long idStart = 0L;
            List<ZombieFanPassiveTask> zombieFanPassiveTaskList = zombieFanPassiveTaskMapper.findByList(page, zombieFanPassiveTaskQuery);
            while (zombieFanPassiveTaskList != null && zombieFanPassiveTaskList.size() > 0) {
                for (ZombieFanPassiveTask zombieFanPassiveTask : zombieFanPassiveTaskList) {
                    try {
                        if (zombieFanPassiveTask.getId().longValue() > idStart.longValue()) {
                            idStart = zombieFanPassiveTask.getId();
                        }

                        //限流判断
                        String rateLimitKey = "autoZombieFanPassiveTask-Id=" + zombieFanPassiveTask.getId();
                        boolean inRateLimit = ratelimitService.inRateLimit(rateLimitKey, 1, 5);
                        if (!inRateLimit) {
                            //logger.info("--inRateLimit false. tradeno={}",alipayDetail.getTradeno());
                            continue;
                        }

                        //ZombieFanPassiveSendPara sendPara = JSONObject.parseObject(zombieFanPassiveTask.getSendPara(), ZombieFanPassiveSendPara.class);

                        //开始限制时间（HH:mm）
                        String limitTimeStart = zombieFanPassiveTask.getLimitTimeStart();
                        if (StringUtils.isBlank(limitTimeStart)) {
                            limitTimeStart = "00:00";
                        }

                        //结束限制时间（HH:mm）
                        String limitTimeEnd = zombieFanPassiveTask.getLimitTimeEnd();
                        if (StringUtils.isBlank(limitTimeEnd)) {
                            limitTimeEnd = "23:59";
                        }

                        //判断当前时间是否在自动任务开启时间区间内
                        boolean withinTimeInterval = Tools.isWithinTimeInterval(now_localDateTime, LocalTime.parse(limitTimeStart), LocalTime.parse(limitTimeEnd));
                        //不在区间内，则跳过
                        if (!withinTimeInterval) {
                            continue;
                        }

                        //发送间隔最小时间
                        Integer rateMin = Tools.getInteger(zombieFanPassiveTask.getRateMin());
                        //发送间隔最大时间
                        Integer rateMax = Tools.getInteger(zombieFanPassiveTask.getRateMax());
                        //上次发送时间
                        Integer sendTime = Tools.getInteger(zombieFanPassiveTask.getSendTime());
                        //这次发送时间,默认等于当前时间
                        int sendTimeNew = now;
                        if (sendTime.intValue() != 0) { //已经开始发送配置方案
                            if (sendTime.intValue() + rateMin.intValue() * 60 > now) {//上次发送时间+最小时间间隔，如果还大于当前时间，表示还未轮到，
                                continue;
                            }

                            //判断旧发送时间是否在允许区间内
                            Instant instant_sendTime = Instant.ofEpochMilli(sendTime * 1000L);
                            LocalDateTime localDateTime_sendTime = LocalDateTime.ofInstant(instant_sendTime, ZoneId.systemDefault());
                            boolean withinTimeInterval_sendTime = Tools.isWithinTimeInterval(localDateTime_sendTime, LocalTime.parse(limitTimeStart), LocalTime.parse(limitTimeEnd));
                            //不在区间内，则新发送时间为当前时间
                            if (!withinTimeInterval_sendTime) {
                                sendTimeNew = now;
                            } else {
                                //旧发送时间在允许区间内，需要判断上次发送是否在当天，如果是当天表示已经发送过一次，需要判断是否只发送一次,如果是，则跳过不发送
                                //获取最小和最大时间的随机数（分数）
                                int random = (int) (Math.random() * (rateMax - rateMin + 1) + rateMin);
                                sendTimeNew = sendTime + random * 60;
                            }
                        } else { //如果等于空，则表示第一次发送，默认为0
                            sendTimeNew = now;
                        }

                        //如果发送时间小于当前时间，则默认按照当前时间来发
                        if (sendTimeNew < now) {
                            sendTimeNew = now;
                        }

                        //判断新发送时间是否在允许区间内，不在则跳过
                        Instant instant_sendTimeNew = Instant.ofEpochMilli(sendTimeNew * 1000L);
                        LocalDateTime localDateTime_sendTimeNew = LocalDateTime.ofInstant(instant_sendTimeNew, ZoneId.systemDefault());
                        boolean withinTimeInterval_sendTimeNew = Tools.isWithinTimeInterval(localDateTime_sendTimeNew, LocalTime.parse(limitTimeStart), LocalTime.parse(limitTimeEnd));
                        //不在区间内，则跳过
                        if (!withinTimeInterval_sendTimeNew) {
                            continue;
                        }

                        //更新新的发送时间
                        zombieFanPassiveTask.setSendTime(sendTimeNew);

                        //自动添加被动僵尸粉
                        zombieFanPassiveTaskService.autoAddZombieFanPassive(zombieFanPassiveTask);

                        //保存成功之后，手动删除限流redisKey
                        redisTemplate.delete(rateLimitKey);
                    } catch (Exception e) {
                        logger.error("--自动处理被动僵尸粉任务--error={}", e.getMessage());
                    }
                }

                zombieFanPassiveTaskQuery.setIdStart(idStart);
                zombieFanPassiveTaskList = zombieFanPassiveTaskMapper.findByList(page, zombieFanPassiveTaskQuery);

            }
        } catch (Exception e) {
            logger.info(e.getMessage());
        } finally {
            //删除限流key
            redisTemplate.delete(taskLimitKet);
        }

    }

    /**
     * 自动清理被动僵尸粉任务发送记录
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void autoDeleteZombieFanPassiveTaskSendInfo() {
        int deleteDay = DateUtil.getNowTime() - 24 * 3600;
        zombieFanPassiveTaskSendInfoMapper.deleteBeforeDay(deleteDay);
    }

    /**
     * 自动刷新钉钉报警群每月免费发送消息数
     *
     * @param
     * @return null
     * @author liuqi
     * @date 2021/8/13 11:38
     */
    @Async("taskExecutor")
    public void autoRefreshDingWarningGroup() {
        logger.info("-----自动刷新钉钉报警群每月免费发送消息数任务--xxlJob start--");

        //查询当前所有开启的自动发圈的配置方案
        int now = DateUtil.getNowTime();

        // 获取当前时间
        LocalDateTime now_localDateTime = LocalDateTime.now();

        String yyyyMMdd = Tools.getDateFormat(new Date(), "yyyy-MM-dd");

        DingWarningGroupQuery dingWarningGroupQuery = new DingWarningGroupQuery();

        //查询所有的自动发圈配置记录
        Page<DingWarningGroup> page = new Page<>();
        page.setCurrent(1);//只查第一页
        page.setSize(10); //每页查询10个
        page.addOrder(OrderItem.asc("id"));//默认id升序
        Long idStart = 0L;
        List<DingWarningGroup> dingWarningGroupList = dingWarningGroupMapper.queryDingWarningGroupList(page, dingWarningGroupQuery);
        while (dingWarningGroupList != null && dingWarningGroupList.size() > 0) {
            for (DingWarningGroup dingWarningGroup : dingWarningGroupList) {
                try {
                    if (dingWarningGroup.getId().longValue() > idStart.longValue()) {
                        idStart = dingWarningGroup.getId();
                    }

                    //限流判断
                    String rateLimitKey = "autoRefreshDingWarningGroup-Id=" + dingWarningGroup.getId();
                    boolean inRateLimit = ratelimitService.inRateLimit(rateLimitKey, 1, 10);
                    if (!inRateLimit) {
                        //logger.info("--inRateLimit false. tradeno={}",alipayDetail.getTradeno());
                        continue;
                    }

                    //上次免费次数修改时间
                    Integer freeMsgUpdateTime = dingWarningGroup.getFreeMsgUpdateTime();

                    //旧发送时间在允许区间内，需要判断上次发送是否在当天，如果是当天表示已经发送过一次，需要判断是否只发送一次,如果是，则跳过不发送
                    //判断当前时间跟上次处理僵尸粉时间是否是同一天
                    if (DateUtil.isSameMonth(new Date(freeMsgUpdateTime * 1000L), new Date())) {//是同一月，则不刷新免费消息条数
                        continue;
                    }

                    //更新钉钉报警群免费消息数
                    dingWarningGroup.setFreeMsg(uzaiConsoleSysConfig.getDingdingWarningGroupFreeMsgNum()); //每月免费200
                    //获取当月免费已使用数
                    Integer freeUsedMsg = Tools.getInteger(dingWarningGroup.getFreeUsedMsg());
                    //获取免费总使用数
                    Integer freeUsedTotal = Tools.getInteger(dingWarningGroup.getFreeUsedTotal());
                    //重置免费消息已使用数
                    dingWarningGroup.setFreeUsedMsg(0);
                    //累加免费消息总使用数
                    dingWarningGroup.setFreeUsedTotal(freeUsedTotal + freeUsedMsg);
                    dingWarningGroup.setFreeMsgUpdateTime(now);
                    dingWarningGroup.setUpdateTime(now);
                    //更新免费消息对象
                    int i = dingWarningGroupMapper.updateFreeMsg(dingWarningGroup);

                    if (i == 1) {
                        //增加钉钉群报警消息购买明细
                        DingWarningGroupDetail dingWarningGroupDetail = new DingWarningGroupDetail();
                        dingWarningGroupDetail.setId(IdWorker.getId());
                        dingWarningGroupDetail.setMerId(dingWarningGroup.getMerId());
                        dingWarningGroupDetail.setDingWarningGroupId(dingWarningGroup.getId());
                        //业务号
                        String trandeno = Tools.getCurrentTimeByFormat("yyyyMMdd") + IdWorker.getIdStr();
                        dingWarningGroupDetail.setTradeno(trandeno);
                        dingWarningGroupDetail.setType(0);    //付费
                        dingWarningGroupDetail.setMsgNum(uzaiConsoleSysConfig.getDingdingWarningGroupFreeMsgNum());
                        dingWarningGroupDetail.setCreateTime(now);
                        dingWarningGroupDetail.setUpdateTime(now);
                        int j = dingWarningGroupDetailMapper.insert(dingWarningGroupDetail);
                    }

                    //保存成功之后，手动删除限流redisKey
                    redisTemplate.delete(rateLimitKey);
                } catch (Exception e) {
                    logger.error("--自动刷新钉钉报警群每月免费发送消息数任务--error={}", e.getMessage());
                }
            }

            dingWarningGroupQuery.setIdStart(idStart);
            dingWarningGroupList = dingWarningGroupMapper.queryDingWarningGroupList(page, dingWarningGroupQuery);
        }
    }

    @Override
    public void reloadGroupCreateTask() {

        List<GroupCreateTask> groupCreateTasks = groupCreateTaskService.listByStatus(2);
        if (ObjectUtils.isEmpty(groupCreateTasks)) {
            return;
        }
        //
        for (GroupCreateTask groupCreateTask : groupCreateTasks) {

            groupCreateTaskService.execute(groupCreateTask);
        }
    }

    @Async("taskExecutor")
    public void contractSignPollingTask() {
        ContractSignQuery query = new ContractSignQuery();
        query.setStatus(ContractStatusTypeEnum.UNDER_SIGNATURE.getKey());
        // 查询状态为签署中的合同
        ArrayList<SysContract> sysContracts = sysContractMapper.findByList(query);
        if (ObjectUtils.isEmpty(sysContracts)) {
            return;
        }
        ContractOpeDto contractOpeDto = new ContractOpeDto();
        sysContracts.forEach(s -> {
            // 远程调用并更新，因为运营商数量不多 后续自动签署
            contractOpeDto.setSignFlowId(s.getSignFlowId());
            UzaiRespVo<ContractSignInfoVo> uzaiRespVo = uzaiContractFeignService.getContractInfo(contractOpeDto);
            if (uzaiRespVo.getCode() == 200 && uzaiRespVo.getData() != null) {
                sysContractMapper.updateBySingFlowId(s.getSignFlowId(), uzaiRespVo.getData().getStatus());
            }
        });

    }
}
